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        if((hd = shost_priv(host)) == NULL)
1180                return;
1181
1182        mptscsih_shutdown(pdev);
1183
1184        sz1=0;
1185
1186        if (ioc->ScsiLookup != NULL) {
1187                sz1 = ioc->req_depth * sizeof(void *);
1188                kfree(ioc->ScsiLookup);
1189                ioc->ScsiLookup = NULL;
1190        }
1191
1192        dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1193            "Free'd ScsiLookup (%d) memory\n",
1194            ioc->name, sz1));
1195
1196        kfree(hd->info_kbuf);
1197
1198        /* NULL the Scsi_Host pointer
1199         */
1200        ioc->sh = NULL;
1201
1202        scsi_host_put(host);
1203
1204        mpt_detach(pdev);
1205
1206}
1207
1208/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1209/*
1210 *      mptscsih_shutdown - reboot notifier
1211 *
1212 */
1213void
1214mptscsih_shutdown(struct pci_dev *pdev)
1215{
1216}
1217
1218#ifdef CONFIG_PM
1219/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1220/*
1221 *      mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1222 *
1223 *
1224 */
1225int
1226mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1227{
1228        MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1229
1230        scsi_block_requests(ioc->sh);
1231        flush_scheduled_work();
1232        mptscsih_shutdown(pdev);
1233        return mpt_suspend(pdev,state);
1234}
1235
1236/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1237/*
1238 *      mptscsih_resume - Fusion MPT scsi driver resume routine.
1239 *
1240 *
1241 */
1242int
1243mptscsih_resume(struct pci_dev *pdev)
1244{
1245        MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1246        int rc;
1247
1248        rc = mpt_resume(pdev);
1249        scsi_unblock_requests(ioc->sh);
1250        return rc;
1251}
1252
1253#endif
1254
1255/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1256/**
1257 *      mptscsih_info - Return information about MPT adapter
1258 *      @SChost: Pointer to Scsi_Host structure
1259 *
1260 *      (linux scsi_host_template.info routine)
1261 *
1262 *      Returns pointer to buffer where information was written.
1263 */
1264const char *
1265mptscsih_info(struct Scsi_Host *SChost)
1266{
1267        MPT_SCSI_HOST *h;
1268        int size = 0;
1269
1270        h = shost_priv(SChost);
1271
1272        if (h->info_kbuf == NULL)
1273                if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1274                        return h->info_kbuf;
1275        h->info_kbuf[0] = '\0';
1276
1277        mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1278        h->info_kbuf[size-1] = '\0';
1279
1280        return h->info_kbuf;
1281}
1282
1283int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
1284{
1285        MPT_SCSI_HOST   *hd = shost_priv(host);
1286        MPT_ADAPTER     *ioc = hd->ioc;
1287
1288        seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
1289        seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1290        seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
1291        seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
1292
1293        return 0;
1294}
1295
1296/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1297#define ADD_INDEX_LOG(req_ent)  do { } while(0)
1298
1299/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1300/**
1301 *      mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1302 *      @SCpnt: Pointer to scsi_cmnd structure
1303 *
1304 *      (linux scsi_host_template.queuecommand routine)
1305 *      This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1306 *      from a linux scsi_cmnd request and send it to the IOC.
1307 *
1308 *      Returns 0. (rtn value discarded by linux scsi mid-layer)
1309 */
1310int
1311mptscsih_qcmd(struct scsi_cmnd *SCpnt)
1312{
1313        MPT_SCSI_HOST           *hd;
1314        MPT_FRAME_HDR           *mf;
1315        SCSIIORequest_t         *pScsiReq;
1316        VirtDevice              *vdevice = SCpnt->device->hostdata;
1317        u32      datalen;
1318        u32      scsictl;
1319        u32      scsidir;
1320        u32      cmd_len;
1321        int      my_idx;
1322        int      ii;
1323        MPT_ADAPTER *ioc;
1324
1325        hd = shost_priv(SCpnt->device->host);
1326        ioc = hd->ioc;
1327
1328        dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
1329                ioc->name, SCpnt));
1330
1331        if (ioc->taskmgmt_quiesce_io)
1332                return SCSI_MLQUEUE_HOST_BUSY;
1333
1334        /*
1335         *  Put together a MPT SCSI request...
1336         */
1337        if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1338                dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1339                                ioc->name));
1340                return SCSI_MLQUEUE_HOST_BUSY;
1341        }
1342
1343        pScsiReq = (SCSIIORequest_t *) mf;
1344
1345        my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1346
1347        ADD_INDEX_LOG(my_idx);
1348
1349        /*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1350         *    Seems we may receive a buffer (datalen>0) even when there
1351         *    will be no data transfer!  GRRRRR...
1352         */
1353        if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1354                datalen = scsi_bufflen(SCpnt);
1355                scsidir = MPI_SCSIIO_CONTROL_READ;      /* DATA IN  (host<--ioc<--dev) */
1356        } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1357                datalen = scsi_bufflen(SCpnt);
1358                scsidir = MPI_SCSIIO_CONTROL_WRITE;     /* DATA OUT (host-->ioc-->dev) */
1359        } else {
1360                datalen = 0;
1361                scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1362        }
1363
1364        /* Default to untagged. Once a target structure has been allocated,
1365         * use the Inquiry data to determine if device supports tagged.
1366         */
1367        if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) &&
1368            SCpnt->device->tagged_supported)
1369                scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1370        else
1371                scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1372
1373
1374        /* Use the above information to set up the message frame
1375         */
1376        pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1377        pScsiReq->Bus = vdevice->vtarget->channel;
1378        pScsiReq->ChainOffset = 0;
1379        if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1380                pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1381        else
1382                pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1383        pScsiReq->CDBLength = SCpnt->cmd_len;
1384        pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1385        pScsiReq->Reserved = 0;
1386        pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1387        int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1388        pScsiReq->Control = cpu_to_le32(scsictl);
1389
1390        /*
1391         *  Write SCSI CDB into the message
1392         */
1393        cmd_len = SCpnt->cmd_len;
1394        for (ii=0; ii < cmd_len; ii++)
1395                pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1396
1397        for (ii=cmd_len; ii < 16; ii++)
1398                pScsiReq->CDB[ii] = 0;
1399
1400        /* DataLength */
1401        pScsiReq->DataLength = cpu_to_le32(datalen);
1402
1403        /* SenseBuffer low address */
1404        pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1405                                           + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1406
1407        /* Now add the SG list
1408         * Always have a SGE even if null length.
1409         */
1410        if (datalen == 0) {
1411                /* Add a NULL SGE */
1412                ioc->add_sge((char *)&pScsiReq->SGL,
1413                        MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1414                        (dma_addr_t) -1);
1415        } else {
1416                /* Add a 32 or 64 bit SGE */
1417                if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1418                        goto fail;
1419        }
1420
1421        SCpnt->host_scribble = (unsigned char *)mf;
1422        mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1423
1424        mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1425        dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1426                        ioc->name, SCpnt, mf, my_idx));
1427        DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1428        return 0;
1429
1430 fail:
1431        mptscsih_freeChainBuffers(ioc, my_idx);
1432        mpt_free_msg_frame(ioc, mf);
1433        return SCSI_MLQUEUE_HOST_BUSY;
1434}
1435
1436/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1437/*
1438 *      mptscsih_freeChainBuffers - Function to free chain buffers associated
1439 *      with a SCSI IO request
1440 *      @hd: Pointer to the MPT_SCSI_HOST instance
1441 *      @req_idx: Index of the SCSI IO request frame.
1442 *
1443 *      Called if SG chain buffer allocation fails and mptscsih callbacks.
1444 *      No return.
1445 */
1446static void
1447mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1448{
1449        MPT_FRAME_HDR *chain;
1450        unsigned long flags;
1451        int chain_idx;
1452        int next;
1453
1454        /* Get the first chain index and reset
1455         * tracker state.
1456         */
1457        chain_idx = ioc->ReqToChain[req_idx];
1458        ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1459
1460        while (chain_idx != MPT_HOST_NO_CHAIN) {
1461
1462                /* Save the next chain buffer index */
1463                next = ioc->ChainToChain[chain_idx];
1464
1465                /* Free this chain buffer and reset
1466                 * tracker
1467                 */
1468                ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1469
1470                chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1471                                        + (chain_idx * ioc->req_sz));
1472
1473                spin_lock_irqsave(&ioc->FreeQlock, flags);
1474                list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1475                spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1476
1477                dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1478                                ioc->name, chain_idx));
1479
1480                /* handle next */
1481                chain_idx = next;
1482        }
1483        return;
1484}
1485
1486/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1487/*
1488 *      Reset Handling
1489 */
1490
1491/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1492/**
1493 *      mptscsih_IssueTaskMgmt - Generic send Task Management function.
1494 *      @hd: Pointer to MPT_SCSI_HOST structure
1495 *      @type: Task Management type
1496 *      @channel: channel number for task management
1497 *      @id: Logical Target ID for reset (if appropriate)
1498 *      @lun: Logical Unit for reset (if appropriate)
1499 *      @ctx2abort: Context for the task to be aborted (if appropriate)
1500 *      @timeout: timeout for task management control
1501 *
1502 *      Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1503 *      or a non-interrupt thread.  In the former, must not call schedule().
1504 *
1505 *      Not all fields are meaningfull for all task types.
1506 *
1507 *      Returns 0 for SUCCESS, or FAILED.
1508 *
1509 **/
1510int
1511mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
1512        int ctx2abort, ulong timeout)
1513{
1514        MPT_FRAME_HDR   *mf;
1515        SCSITaskMgmt_t  *pScsiTm;
1516        int              ii;
1517        int              retval;
1518        MPT_ADAPTER     *ioc = hd->ioc;
1519        unsigned long    timeleft;
1520        u8               issue_hard_reset;
1521        u32              ioc_raw_state;
1522        unsigned long    time_count;
1523
1524        issue_hard_reset = 0;
1525        ioc_raw_state = mpt_GetIocState(ioc, 0);
1526
1527        if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1528                printk(MYIOC_s_WARN_FMT
1529                        "TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1530                        ioc->name, type, ioc_raw_state);
1531                printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1532                    ioc->name, __func__);
1533                if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1534                        printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1535                            "FAILED!!\n", ioc->name);
1536                return 0;
1537        }
1538
1539        /* DOORBELL ACTIVE check is not required if
1540        *  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
1541        */
1542
1543        if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
1544                 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
1545                (ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1546                printk(MYIOC_s_WARN_FMT
1547                        "TaskMgmt type=%x: ioc_state: "
1548                        "DOORBELL_ACTIVE (0x%x)!\n",
1549                        ioc->name, type, ioc_raw_state);
1550                return FAILED;
1551        }
1552
1553        mutex_lock(&ioc->taskmgmt_cmds.mutex);
1554        if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1555                mf = NULL;
1556                retval = FAILED;
1557                goto out;
1558        }
1559
1560        /* Return Fail to calling function if no message frames available.
1561         */
1562        if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1563                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1564                        "TaskMgmt no msg frames!!\n", ioc->name));
1565                retval = FAILED;
1566                mpt_clear_taskmgmt_in_progress_flag(ioc);
1567                goto out;
1568        }
1569        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1570                        ioc->name, mf));
1571
1572        /* Format the Request
1573         */
1574        pScsiTm = (SCSITaskMgmt_t *) mf;
1575        pScsiTm->TargetID = id;
1576        pScsiTm->Bus = channel;
1577        pScsiTm->ChainOffset = 0;
1578        pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1579
1580        pScsiTm->Reserved = 0;
1581        pScsiTm->TaskType = type;
1582        pScsiTm->Reserved1 = 0;
1583        pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1584                    ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1585
1586        int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1587
1588        for (ii=0; ii < 7; ii++)
1589                pScsiTm->Reserved2[ii] = 0;
1590
1591        pScsiTm->TaskMsgContext = ctx2abort;
1592
1593        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1594                "task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1595                type, timeout));
1596
1597        DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1598
1599        INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1600        time_count = jiffies;
1601        if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1602            (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1603                mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1604        else {
1605                retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1606                        sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1607                if (retval) {
1608                        dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1609                                "TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1610                                ioc->name, mf, retval));
1611                        mpt_free_msg_frame(ioc, mf);
1612                        mpt_clear_taskmgmt_in_progress_flag(ioc);
1613                        goto out;
1614                }
1615        }
1616
1617        timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1618                timeout*HZ);
1619        if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1620                retval = FAILED;
1621                dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1622                    "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1623                mpt_clear_taskmgmt_in_progress_flag(ioc);
1624                if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1625                        goto out;
1626                issue_hard_reset = 1;
1627                goto out;
1628        }
1629
1630        retval = mptscsih_taskmgmt_reply(ioc, type,
1631            (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1632
1633        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1634            "TaskMgmt completed (%d seconds)\n",
1635            ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1636
1637 out:
1638
1639        CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1640        if (issue_hard_reset) {
1641                printk(MYIOC_s_WARN_FMT
1642                       "Issuing Reset from %s!! doorbell=0x%08x\n",
1643                       ioc->name, __func__, mpt_GetIocState(ioc, 0));
1644                retval = (ioc->bus_type == SAS) ?
1645                        mpt_HardResetHandler(ioc, CAN_SLEEP) :
1646                        mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1647                mpt_free_msg_frame(ioc, mf);
1648        }
1649
1650        retval = (retval == 0) ? 0 : FAILED;
1651        mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1652        return retval;
1653}
1654EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1655
1656static int
1657mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1658{
1659        switch (ioc->bus_type) {
1660        case FC:
1661                return 40;
1662        case SAS:
1663                return 30;
1664        case SPI:
1665        default:
1666                return 10;
1667        }
1668}
1669
1670/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1671/**
1672 *      mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1673 *      @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1674 *
1675 *      (linux scsi_host_template.eh_abort_handler routine)
1676 *
1677 *      Returns SUCCESS or FAILED.
1678 **/
1679int
1680mptscsih_abort(struct scsi_cmnd * SCpnt)
1681{
1682        MPT_SCSI_HOST   *hd;
1683        MPT_FRAME_HDR   *mf;
1684        u32              ctx2abort;
1685        int              scpnt_idx;
1686        int              retval;
1687        VirtDevice       *vdevice;
1688        MPT_ADAPTER     *ioc;
1689
1690        /* If we can't locate our host adapter structure, return FAILED status.
1691         */
1692        if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1693                SCpnt->result = DID_RESET << 16;
1694                SCpnt->scsi_done(SCpnt);
1695                printk(KERN_ERR MYNAM ": task abort: "
1696                    "can't locate host! (sc=%p)\n", SCpnt);
1697                return FAILED;
1698        }
1699
1700        ioc = hd->ioc;
1701        printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1702               ioc->name, SCpnt);
1703        scsi_print_command(SCpnt);
1704
1705        vdevice = SCpnt->device->hostdata;
1706        if (!vdevice || !vdevice->vtarget) {
1707                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1708                    "task abort: device has been deleted (sc=%p)\n",
1709                    ioc->name, SCpnt));
1710                SCpnt->result = DID_NO_CONNECT << 16;
1711                SCpnt->scsi_done(SCpnt);
1712                retval = SUCCESS;
1713                goto out;
1714        }
1715
1716        /* Task aborts are not supported for hidden raid components.
1717         */
1718        if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1719                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1720                    "task abort: hidden raid component (sc=%p)\n",
1721                    ioc->name, SCpnt));
1722                SCpnt->result = DID_RESET << 16;
1723                retval = FAILED;
1724                goto out;
1725        }
1726
1727        /* Task aborts are not supported for volumes.
1728         */
1729        if (vdevice->vtarget->raidVolume) {
1730                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1731                    "task abort: raid volume (sc=%p)\n",
1732                    ioc->name, SCpnt));
1733                SCpnt->result = DID_RESET << 16;
1734                retval = FAILED;
1735                goto out;
1736        }
1737
1738        /* Find this command
1739         */
1740        if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1741                /* Cmd not found in ScsiLookup.
1742                 * Do OS callback.
1743                 */
1744                SCpnt->result = DID_RESET << 16;
1745                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1746                   "Command not in the active list! (sc=%p)\n", ioc->name,
1747                   SCpnt));
1748                retval = SUCCESS;
1749                goto out;
1750        }
1751
1752        if (ioc->timeouts < -1)
1753                ioc->timeouts++;
1754
1755        if (mpt_fwfault_debug)
1756                mpt_halt_firmware(ioc);
1757
1758        /* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1759         * (the IO to be ABORT'd)
1760         *
1761         * NOTE: Since we do not byteswap MsgContext, we do not
1762         *       swap it here either.  It is an opaque cookie to
1763         *       the controller, so it does not matter. -DaveM
1764         */
1765        mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1766        ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1767        retval = mptscsih_IssueTaskMgmt(hd,
1768                         MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1769                         vdevice->vtarget->channel,
1770                         vdevice->vtarget->id, vdevice->lun,
1771                         ctx2abort, mptscsih_get_tm_timeout(ioc));
1772
1773        if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
1774                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1775                    "task abort: command still in active list! (sc=%p)\n",
1776                    ioc->name, SCpnt));
1777                retval = FAILED;
1778        } else {
1779                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1780                    "task abort: command cleared from active list! (sc=%p)\n",
1781                    ioc->name, SCpnt));
1782                retval = SUCCESS;
1783        }
1784
1785 out:
1786        printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
1787            ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
1788            SCpnt);
1789
1790        return retval;
1791}
1792
1793/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1794/**
1795 *      mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1796 *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1797 *
1798 *      (linux scsi_host_template.eh_dev_reset_handler routine)
1799 *
1800 *      Returns SUCCESS or FAILED.
1801 **/
1802int
1803mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1804{
1805        MPT_SCSI_HOST   *hd;
1806        int              retval;
1807        VirtDevice       *vdevice;
1808        MPT_ADAPTER     *ioc;
1809
1810        /* If we can't locate our host adapter structure, return FAILED status.
1811         */
1812        if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1813                printk(KERN_ERR MYNAM ": target reset: "
1814                   "Can't locate host! (sc=%p)\n", SCpnt);
1815                return FAILED;
1816        }
1817
1818        ioc = hd->ioc;
1819        printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1820               ioc->name, SCpnt);
1821        scsi_print_command(SCpnt);
1822
1823        vdevice = SCpnt->device->hostdata;
1824        if (!vdevice || !vdevice->vtarget) {
1825                retval = 0;
1826                goto out;
1827        }
1828
1829        /* Target reset to hidden raid component is not supported
1830         */
1831        if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1832                retval = FAILED;
1833                goto out;
1834        }
1835
1836        retval = mptscsih_IssueTaskMgmt(hd,
1837                                MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1838                                vdevice->vtarget->channel,
1839                                vdevice->vtarget->id, 0, 0,
1840                                mptscsih_get_tm_timeout(ioc));
1841
1842 out:
1843        printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1844            ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1845
1846        if (retval == 0)
1847                return SUCCESS;
1848        else
1849                return FAILED;
1850}
1851
1852
1853/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1854/**
1855 *      mptscsih_bus_reset - Perform a SCSI BUS_RESET!  new_eh variant
1856 *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1857 *
1858 *      (linux scsi_host_template.eh_bus_reset_handler routine)
1859 *
1860 *      Returns SUCCESS or FAILED.
1861 **/
1862int
1863mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1864{
1865        MPT_SCSI_HOST   *hd;
1866        int              retval;
1867        VirtDevice       *vdevice;
1868        MPT_ADAPTER     *ioc;
1869
1870        /* If we can't locate our host adapter structure, return FAILED status.
1871         */
1872        if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1873                printk(KERN_ERR MYNAM ": bus reset: "
1874                   "Can't locate host! (sc=%p)\n", SCpnt);
1875                return FAILED;
1876        }
1877
1878        ioc = hd->ioc;
1879        printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1880               ioc->name, SCpnt);
1881        scsi_print_command(SCpnt);
1882
1883        if (ioc->timeouts < -1)
1884                ioc->timeouts++;
1885
1886        vdevice = SCpnt->device->hostdata;
1887        if (!vdevice || !vdevice->vtarget)
1888                return SUCCESS;
1889        retval = mptscsih_IssueTaskMgmt(hd,
1890                                        MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1891                                        vdevice->vtarget->channel, 0, 0, 0,
1892                                        mptscsih_get_tm_timeout(ioc));
1893
1894        printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1895            ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1896
1897        if (retval == 0)
1898                return SUCCESS;
1899        else
1900                return FAILED;
1901}
1902
1903/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1904/**
1905 *      mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1906 *      @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1907 *
1908 *      (linux scsi_host_template.eh_host_reset_handler routine)
1909 *
1910 *      Returns SUCCESS or FAILED.
1911 */
1912int
1913mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1914{
1915        MPT_SCSI_HOST *  hd;
1916        int              status = SUCCESS;
1917        MPT_ADAPTER     *ioc;
1918        int             retval;
1919
1920        /*  If we can't locate the host to reset, then we failed. */
1921        if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1922                printk(KERN_ERR MYNAM ": host reset: "
1923                    "Can't locate host! (sc=%p)\n", SCpnt);
1924                return FAILED;
1925        }
1926
1927        /* make sure we have no outstanding commands at this stage */
1928        mptscsih_flush_running_cmds(hd);
1929
1930        ioc = hd->ioc;
1931        printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
1932            ioc->name, SCpnt);
1933
1934        /*  If our attempts to reset the host failed, then return a failed
1935         *  status.  The host will be taken off line by the SCSI mid-layer.
1936         */
1937    retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1938        if (retval < 0)
1939                status = FAILED;
1940        else
1941                status = SUCCESS;
1942
1943        printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1944            ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1945
1946        return status;
1947}
1948
1949static int
1950mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
1951        SCSITaskMgmtReply_t *pScsiTmReply)
1952{
1953        u16                      iocstatus;
1954        u32                      termination_count;
1955        int                      retval;
1956
1957        if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
1958                retval = FAILED;
1959                goto out;
1960        }
1961
1962        DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
1963
1964        iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
1965        termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
1966
1967        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1968            "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
1969            "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
1970            "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
1971            pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
1972            le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
1973            termination_count));
1974
1975        if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
1976            pScsiTmReply->ResponseCode)
1977                mptscsih_taskmgmt_response_code(ioc,
1978                    pScsiTmReply->ResponseCode);
1979
1980        if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
1981                retval = 0;
1982                goto out;
1983        }
1984
1985        retval = FAILED;
1986        if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1987                if (termination_count == 1)
1988                        retval = 0;
1989                goto out;
1990        }
1991
1992        if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1993           iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1994                retval = 0;
1995
1996 out:
1997        return retval;
1998}
1999
2000/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2001void
2002mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2003{
2004        char *desc;
2005
2006        switch (response_code) {
2007        case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2008                desc = "The task completed.";
2009                break;
2010        case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2011                desc = "The IOC received an invalid frame status.";
2012                break;
2013        case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2014                desc = "The task type is not supported.";
2015                break;
2016        case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2017                desc = "The requested task failed.";
2018                break;
2019        case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2020                desc = "The task completed successfully.";
2021                break;
2022        case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2023                desc = "The LUN request is invalid.";
2024                break;
2025        case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2026                desc = "The task is in the IOC queue and has not been sent to target.";
2027                break;
2028        default:
2029                desc = "unknown";
2030                break;
2031        }
2032        printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2033                ioc->name, response_code, desc);
2034}
2035EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2036
2037/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2038/**
2039 *      mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2040 *      @ioc: Pointer to MPT_ADAPTER structure
2041 *      @mf: Pointer to SCSI task mgmt request frame
2042 *      @mr: Pointer to SCSI task mgmt reply frame
2043 *
2044 *      This routine is called from mptbase.c::mpt_interrupt() at the completion
2045 *      of any SCSI task management request.
2046 *      This routine is registered with the MPT (base) driver at driver
2047 *      load/init time via the mpt_register() API call.
2048 *
2049 *      Returns 1 indicating alloc'd request frame ptr should be freed.
2050 **/
2051int
2052mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2053        MPT_FRAME_HDR *mr)
2054{
2055        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2056                "TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2057
2058        ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2059
2060        if (!mr)
2061                goto out;
2062
2063        ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2064        memcpy(ioc->taskmgmt_cmds.reply, mr,
2065            min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2066 out:
2067        if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2068                mpt_clear_taskmgmt_in_progress_flag(ioc);
2069                ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2070                complete(&ioc->taskmgmt_cmds.done);
2071                if (ioc->bus_type == SAS)
2072                        ioc->schedule_target_reset(ioc);
2073                return 1;
2074        }
2075        return 0;
2076}
2077
2078/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2079/*
2080 *      This is anyones guess quite frankly.
2081 */
2082int
2083mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2084                sector_t capacity, int geom[])
2085{
2086        int             heads;
2087        int             sectors;
2088        sector_t        cylinders;
2089        ulong           dummy;
2090
2091        heads = 64;
2092        sectors = 32;
2093
2094        dummy = heads * sectors;
2095        cylinders = capacity;
2096        sector_div(cylinders,dummy);
2097
2098        /*
2099         * Handle extended translation size for logical drives
2100         * > 1Gb
2101         */
2102        if ((ulong)capacity >= 0x200000) {
2103                heads = 255;
2104                sectors = 63;
2105                dummy = heads * sectors;
2106                cylinders = capacity;
2107                sector_div(cylinders,dummy);
2108        }
2109
2110        /* return result */
2111        geom[0] = heads;
2112        geom[1] = sectors;
2113        geom[2] = cylinders;
2114
2115        return 0;
2116}
2117
2118/* Search IOC page 3 to determine if this is hidden physical disk
2119 *
2120 */
2121int
2122mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2123{
2124        struct inactive_raid_component_info *component_info;
2125        int i, j;
2126        RaidPhysDiskPage1_t *phys_disk;
2127        int rc = 0;
2128        int num_paths;
2129
2130        if (!ioc->raid_data.pIocPg3)
2131                goto out;
2132        for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2133                if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2134                    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2135                        rc = 1;
2136                        goto out;
2137                }
2138        }
2139
2140        if (ioc->bus_type != SAS)
2141                goto out;
2142
2143        /*
2144         * Check if dual path
2145         */
2146        for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2147                num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2148                    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2149                if (num_paths < 2)
2150                        continue;
2151                phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2152                   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2153                if (!phys_disk)
2154                        continue;
2155                if ((mpt_raid_phys_disk_pg1(ioc,
2156                    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2157                    phys_disk))) {
2158                        kfree(phys_disk);
2159                        continue;
2160                }
2161                for (j = 0; j < num_paths; j++) {
2162                        if ((phys_disk->Path[j].Flags &
2163                            MPI_RAID_PHYSDISK1_FLAG_INVALID))
2164                                continue;
2165                        if ((phys_disk->Path[j].Flags &
2166                            MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2167                                continue;
2168                        if ((id == phys_disk->Path[j].PhysDiskID) &&
2169                            (channel == phys_disk->Path[j].PhysDiskBus)) {
2170                                rc = 1;
2171                                kfree(phys_disk);
2172                                goto out;
2173                        }
2174                }
2175                kfree(phys_disk);
2176        }
2177
2178
2179        /*
2180         * Check inactive list for matching phys disks
2181         */
2182        if (list_empty(&ioc->raid_data.inactive_list))
2183                goto out;
2184
2185        mutex_lock(&ioc->raid_data.inactive_list_mutex);
2186        list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2187            list) {
2188                if ((component_info->d.PhysDiskID == id) &&
2189                    (component_info->d.PhysDiskBus == channel))
2190                        rc = 1;
2191        }
2192        mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2193
2194 out:
2195        return rc;
2196}
2197EXPORT_SYMBOL(mptscsih_is_phys_disk);
2198
2199u8
2200mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2201{
2202        struct inactive_raid_component_info *component_info;
2203        int i, j;
2204        RaidPhysDiskPage1_t *phys_disk;
2205        int rc = -ENXIO;
2206        int num_paths;
2207
2208        if (!ioc->raid_data.pIocPg3)
2209                goto out;
2210        for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2211                if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2212                    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2213                        rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2214                        goto out;
2215                }
2216        }
2217
2218        if (ioc->bus_type != SAS)
2219                goto out;
2220
2221        /*
2222         * Check if dual path
2223         */
2224        for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2225                num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2226                    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2227                if (num_paths < 2)
2228                        continue;
2229                phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2230                   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2231                if (!phys_disk)
2232                        continue;
2233                if ((mpt_raid_phys_disk_pg1(ioc,
2234                    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2235                    phys_disk))) {
2236                        kfree(phys_disk);
2237                        continue;
2238                }
2239                for (j = 0; j < num_paths; j++) {
2240                        if ((phys_disk->Path[j].Flags &
2241                            MPI_RAID_PHYSDISK1_FLAG_INVALID))
2242                                continue;
2243                        if ((phys_disk->Path[j].Flags &
2244                            MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2245                                continue;
2246                        if ((id == phys_disk->Path[j].PhysDiskID) &&
2247                            (channel == phys_disk->Path[j].PhysDiskBus)) {
2248                                rc = phys_disk->PhysDiskNum;
2249                                kfree(phys_disk);
2250                                goto out;
2251                        }
2252                }
2253                kfree(phys_disk);
2254        }
2255
2256        /*
2257         * Check inactive list for matching phys disks
2258         */
2259        if (list_empty(&ioc->raid_data.inactive_list))
2260                goto out;
2261
2262        mutex_lock(&ioc->raid_data.inactive_list_mutex);
2263        list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2264            list) {
2265                if ((component_info->d.PhysDiskID == id) &&
2266                    (component_info->d.PhysDiskBus == channel))
2267                        rc = component_info->d.PhysDiskNum;
2268        }
2269        mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2270
2271 out:
2272        return rc;
2273}
2274EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2275
2276/*
2277 *      OS entry point to allow for host driver to free allocated memory
2278 *      Called if no device present or device being unloaded
2279 */
2280void
2281mptscsih_slave_destroy(struct scsi_device *sdev)
2282{
2283        struct Scsi_Host        *host = sdev->host;
2284        MPT_SCSI_HOST           *hd = shost_priv(host);
2285        VirtTarget              *vtarget;
2286        VirtDevice              *vdevice;
2287        struct scsi_target      *starget;
2288
2289        starget = scsi_target(sdev);
2290        vtarget = starget->hostdata;
2291        vdevice = sdev->hostdata;
2292        if (!vdevice)
2293                return;
2294
2295        mptscsih_search_running_cmds(hd, vdevice);
2296        vtarget->num_luns--;
2297        mptscsih_synchronize_cache(hd, vdevice);
2298        kfree(vdevice);
2299        sdev->hostdata = NULL;
2300}
2301
2302/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2303/*
2304 *      mptscsih_change_queue_depth - This function will set a devices queue depth
2305 *      @sdev: per scsi_device pointer
2306 *      @qdepth: requested queue depth
2307 *
2308 *      Adding support for new 'change_queue_depth' api.
2309*/
2310int
2311mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2312{
2313        MPT_SCSI_HOST           *hd = shost_priv(sdev->host);
2314        VirtTarget              *vtarget;
2315        struct scsi_target      *starget;
2316        int                     max_depth;
2317        MPT_ADAPTER             *ioc = hd->ioc;
2318
2319        starget = scsi_target(sdev);
2320        vtarget = starget->hostdata;
2321
2322        if (ioc->bus_type == SPI) {
2323                if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2324                        max_depth = 1;
2325                else if (sdev->type == TYPE_DISK &&
2326                         vtarget->minSyncFactor <= MPT_ULTRA160)
2327                        max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2328                else
2329                        max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2330        } else
2331                 max_depth = ioc->sh->can_queue;
2332
2333        if (!sdev->tagged_supported)
2334                max_depth = 1;
2335
2336        if (qdepth > max_depth)
2337                qdepth = max_depth;
2338
2339        return scsi_change_queue_depth(sdev, qdepth);
2340}
2341
2342/*
2343 *      OS entry point to adjust the queue_depths on a per-device basis.
2344 *      Called once per device the bus scan. Use it to force the queue_depth
2345 *      member to 1 if a device does not support Q tags.
2346 *      Return non-zero if fails.
2347 */
2348int
2349mptscsih_slave_configure(struct scsi_device *sdev)
2350{
2351        struct Scsi_Host        *sh = sdev->host;
2352        VirtTarget              *vtarget;
2353        VirtDevice              *vdevice;
2354        struct scsi_target      *starget;
2355        MPT_SCSI_HOST           *hd = shost_priv(sh);
2356        MPT_ADAPTER             *ioc = hd->ioc;
2357
2358        starget = scsi_target(sdev);
2359        vtarget = starget->hostdata;
2360        vdevice = sdev->hostdata;
2361
2362        dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2363                "device @ %p, channel=%d, id=%d, lun=%llu\n",
2364                ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2365        if (ioc->bus_type == SPI)
2366                dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2367                    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2368                    ioc->name, sdev->sdtr, sdev->wdtr,
2369                    sdev->ppr, sdev->inquiry_len));
2370
2371        vdevice->configured_lun = 1;
2372
2373        dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2374                "Queue depth=%d, tflags=%x\n",
2375                ioc->name, sdev->queue_depth, vtarget->tflags));
2376
2377        if (ioc->bus_type == SPI)
2378                dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2379                    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2380                    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2381                    vtarget->minSyncFactor));
2382
2383        mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2384        dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2385                "tagged %d, simple %d\n",
2386                ioc->name,sdev->tagged_supported, sdev->simple_tags));
2387
2388        blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2389
2390        return 0;
2391}
2392
2393/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2394/*
2395 *  Private routines...
2396 */
2397
2398/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2399/* Utility function to copy sense data from the scsi_cmnd buffer
2400 * to the FC and SCSI target structures.
2401 *
2402 */
2403static void
2404mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2405{
2406        VirtDevice      *vdevice;
2407        SCSIIORequest_t *pReq;
2408        u32              sense_count = le32_to_cpu(pScsiReply->SenseCount);
2409        MPT_ADAPTER     *ioc = hd->ioc;
2410
2411        /* Get target structure
2412         */
2413        pReq = (SCSIIORequest_t *) mf;
2414        vdevice = sc->device->hostdata;
2415
2416        if (sense_count) {
2417                u8 *sense_data;
2418                int req_index;
2419
2420                /* Copy the sense received into the scsi command block. */
2421                req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2422                sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2423                memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2424
2425                /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2426                 */
2427                if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2428                        if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2429                                int idx;
2430
2431                                idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2432                                ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2433                                ioc->events[idx].eventContext = ioc->eventContext;
2434
2435                                ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2436                                        (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2437                                        (sc->device->channel << 8) | sc->device->id;
2438
2439                                ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2440
2441                                ioc->eventContext++;
2442                                if (ioc->pcidev->vendor ==
2443                                    PCI_VENDOR_ID_IBM) {
2444                                        mptscsih_issue_sep_command(ioc,
2445                                            vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2446                                        vdevice->vtarget->tflags |=
2447                                            MPT_TARGET_FLAGS_LED_ON;
2448                                }
2449                        }
2450                }
2451        } else {
2452                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2453                                ioc->name));
2454        }
2455}
2456
2457/**
2458 * mptscsih_get_scsi_lookup - retrieves scmd entry
2459 * @ioc: Pointer to MPT_ADAPTER structure
2460 * @i: index into the array
2461 *
2462 * Returns the scsi_cmd pointer
2463 */
2464struct scsi_cmnd *
2465mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2466{
2467        unsigned long   flags;
2468        struct scsi_cmnd *scmd;
2469
2470        spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2471        scmd = ioc->ScsiLookup[i];
2472        spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2473
2474        return scmd;
2475}
2476EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2477
2478/**
2479 * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2480 * @ioc: Pointer to MPT_ADAPTER structure
2481 * @i: index into the array
2482 *
2483 * Returns the scsi_cmd pointer
2484 *
2485 **/
2486static struct scsi_cmnd *
2487mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2488{
2489        unsigned long   flags;
2490        struct scsi_cmnd *scmd;
2491
2492        spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2493        scmd = ioc->ScsiLookup[i];
2494        ioc->ScsiLookup[i] = NULL;
2495        spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2496
2497        return scmd;
2498}
2499
2500/**
2501 * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2502 *
2503 * @ioc: Pointer to MPT_ADAPTER structure
2504 * @i: index into the array
2505 * @scmd: scsi_cmnd pointer
2506 *
2507 **/
2508static void
2509mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2510{
2511        unsigned long   flags;
2512
2513        spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2514        ioc->ScsiLookup[i] = scmd;
2515        spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2516}
2517
2518/**
2519 * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2520 * @ioc: Pointer to MPT_ADAPTER structure
2521 * @sc: scsi_cmnd pointer
2522 */
2523static int
2524SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2525{
2526        unsigned long   flags;
2527        int i, index=-1;
2528
2529        spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2530        for (i = 0; i < ioc->req_depth; i++) {
2531                if (ioc->ScsiLookup[i] == sc) {
2532                        index = i;
2533                        goto out;
2534                }
2535        }
2536
2537 out:
2538        spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2539        return index;
2540}
2541
2542/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2543int
2544mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2545{
2546        MPT_SCSI_HOST   *hd;
2547
2548        if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2549                return 0;
2550
2551        hd = shost_priv(ioc->sh);
2552        switch (reset_phase) {
2553        case MPT_IOC_SETUP_RESET:
2554                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2555                    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2556                break;
2557        case MPT_IOC_PRE_RESET:
2558                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2559                    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2560                mptscsih_flush_running_cmds(hd);
2561                break;
2562        case MPT_IOC_POST_RESET:
2563                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2564                    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2565                if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2566                        ioc->internal_cmds.status |=
2567                                MPT_MGMT_STATUS_DID_IOCRESET;
2568                        complete(&ioc->internal_cmds.done);
2569                }
2570                break;
2571        default:
2572                break;
2573        }
2574        return 1;               /* currently means nothing really */
2575}
2576
2577/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2578int
2579mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2580{
2581        u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2582
2583        devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2584                "MPT event (=%02Xh) routed to SCSI host driver!\n",
2585                ioc->name, event));
2586
2587        if ((event == MPI_EVENT_IOC_BUS_RESET ||
2588            event == MPI_EVENT_EXT_BUS_RESET) &&
2589            (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2590                        ioc->soft_resets++;
2591
2592        return 1;               /* currently means nothing really */
2593}
2594
2595/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2596/*
2597 *  Bus Scan and Domain Validation functionality ...
2598 */
2599
2600/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2601/*
2602 *      mptscsih_scandv_complete - Scan and DV callback routine registered
2603 *      to Fustion MPT (base) driver.
2604 *
2605 *      @ioc: Pointer to MPT_ADAPTER structure
2606 *      @mf: Pointer to original MPT request frame
2607 *      @mr: Pointer to MPT reply frame (NULL if TurboReply)
2608 *
2609 *      This routine is called from mpt.c::mpt_interrupt() at the completion
2610 *      of any SCSI IO request.
2611 *      This routine is registered with the Fusion MPT (base) driver at driver
2612 *      load/init time via the mpt_register() API call.
2613 *
2614 *      Returns 1 indicating alloc'd request frame ptr should be freed.
2615 *
2616 *      Remark: Sets a completion code and (possibly) saves sense data
2617 *      in the IOC member localReply structure.
2618 *      Used ONLY for DV and other internal commands.
2619 */
2620int
2621mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2622                                MPT_FRAME_HDR *reply)
2623{
2624        SCSIIORequest_t *pReq;
2625        SCSIIOReply_t   *pReply;
2626        u8               cmd;
2627        u16              req_idx;
2628        u8      *sense_data;
2629        int              sz;
2630
2631        ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2632        ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2633        if (!reply)
2634                goto out;
2635
2636        pReply = (SCSIIOReply_t *) reply;
2637        pReq = (SCSIIORequest_t *) req;
2638        ioc->internal_cmds.completion_code =
2639            mptscsih_get_completion_code(ioc, req, reply);
2640        ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2641        memcpy(ioc->internal_cmds.reply, reply,
2642            min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2643        cmd = reply->u.hdr.Function;
2644        if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2645            (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2646            (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2647                req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2648                sense_data = ((u8 *)ioc->sense_buf_pool +
2649                    (req_idx * MPT_SENSE_BUFFER_ALLOC));
2650                sz = min_t(int, pReq->SenseBufferLength,
2651                    MPT_SENSE_BUFFER_ALLOC);
2652                memcpy(ioc->internal_cmds.sense, sense_data, sz);
2653        }
2654 out:
2655        if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2656                return 0;
2657        ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2658        complete(&ioc->internal_cmds.done);
2659        return 1;
2660}
2661
2662
2663/**
2664 *      mptscsih_get_completion_code - get completion code from MPT request
2665 *      @ioc: Pointer to MPT_ADAPTER structure
2666 *      @req: Pointer to original MPT request frame
2667 *      @reply: Pointer to MPT reply frame (NULL if TurboReply)
2668 *
2669 **/
2670static int
2671mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2672                                MPT_FRAME_HDR *reply)
2673{
2674        SCSIIOReply_t   *pReply;
2675        MpiRaidActionReply_t *pr;
2676        u8               scsi_status;
2677        u16              status;
2678        int              completion_code;
2679
2680        pReply = (SCSIIOReply_t *)reply;
2681        status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2682        scsi_status = pReply->SCSIStatus;
2683
2684        devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2685            "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2686            "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2687            scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2688
2689        switch (status) {
2690
2691        case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:       /* 0x0043 */
2692                completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2693                break;
2694
2695        case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:          /* 0x0046 */
2696        case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
2697        case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:         /* 0x004B */
2698        case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:         /* 0x004C */
2699                completion_code = MPT_SCANDV_DID_RESET;
2700                break;
2701
2702        case MPI_IOCSTATUS_BUSY:
2703        case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2704                completion_code = MPT_SCANDV_BUSY;
2705                break;
2706
2707        case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:          /* 0x0045 */
2708        case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
2709        case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
2710                if (pReply->Function == MPI_FUNCTION_CONFIG) {
2711                        completion_code = MPT_SCANDV_GOOD;
2712                } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2713                        pr = (MpiRaidActionReply_t *)reply;
2714                        if (le16_to_cpu(pr->ActionStatus) ==
2715                                MPI_RAID_ACTION_ASTATUS_SUCCESS)
2716                                completion_code = MPT_SCANDV_GOOD;
2717                        else
2718                                completion_code = MPT_SCANDV_SOME_ERROR;
2719                } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2720                        completion_code = MPT_SCANDV_SENSE;
2721                else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2722                        if (req->u.scsireq.CDB[0] == INQUIRY)
2723                                completion_code = MPT_SCANDV_ISSUE_SENSE;
2724                        else
2725                                completion_code = MPT_SCANDV_DID_RESET;
2726                } else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2727                        completion_code = MPT_SCANDV_DID_RESET;
2728                else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2729                        completion_code = MPT_SCANDV_DID_RESET;
2730                else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2731                        completion_code = MPT_SCANDV_BUSY;
2732                else
2733                        completion_code = MPT_SCANDV_GOOD;
2734                break;
2735
2736        case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:         /* 0x0047 */
2737                if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2738                        completion_code = MPT_SCANDV_DID_RESET;
2739                else
2740                        completion_code = MPT_SCANDV_SOME_ERROR;
2741                break;
2742        default:
2743                completion_code = MPT_SCANDV_SOME_ERROR;
2744                break;
2745
2746        }       /* switch(status) */
2747
2748        devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2749            "  completionCode set to %08xh\n", ioc->name, completion_code));
2750        return completion_code;
2751}
2752
2753/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2754/**
2755 *      mptscsih_do_cmd - Do internal command.
2756 *      @hd: MPT_SCSI_HOST pointer
2757 *      @io: INTERNAL_CMD pointer.
2758 *
2759 *      Issue the specified internally generated command and do command
2760 *      specific cleanup. For bus scan / DV only.
2761 *      NOTES: If command is Inquiry and status is good,
2762 *      initialize a target structure, save the data
2763 *
2764 *      Remark: Single threaded access only.
2765 *
2766 *      Return:
2767 *              < 0 if an illegal command or no resources
2768 *
2769 *                 0 if good
2770 *
2771 *               > 0 if command complete but some type of completion error.
2772 */
2773static int
2774mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2775{
2776        MPT_FRAME_HDR   *mf;
2777        SCSIIORequest_t *pScsiReq;
2778        int              my_idx, ii, dir;
2779        int              timeout;
2780        char             cmdLen;
2781        char             CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2782        u8               cmd = io->cmd;
2783        MPT_ADAPTER *ioc = hd->ioc;
2784        int              ret = 0;
2785        unsigned long    timeleft;
2786        unsigned long    flags;
2787
2788        /* don't send internal command during diag reset */
2789        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2790        if (ioc->ioc_reset_in_progress) {
2791                spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2792                dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2793                        "%s: busy with host reset\n", ioc->name, __func__));
2794                return MPT_SCANDV_BUSY;
2795        }
2796        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2797
2798        mutex_lock(&ioc->internal_cmds.mutex);
2799
2800        /* Set command specific information
2801         */
2802        switch (cmd) {
2803        case INQUIRY:
2804                cmdLen = 6;
2805                dir = MPI_SCSIIO_CONTROL_READ;
2806                CDB[0] = cmd;
2807                CDB[4] = io->size;
2808                timeout = 10;
2809                break;
2810
2811        case TEST_UNIT_READY:
2812                cmdLen = 6;
2813                dir = MPI_SCSIIO_CONTROL_READ;
2814                timeout = 10;
2815                break;
2816
2817        case START_STOP:
2818                cmdLen = 6;
2819                dir = MPI_SCSIIO_CONTROL_READ;
2820                CDB[0] = cmd;
2821                CDB[4] = 1;     /*Spin up the disk */
2822                timeout = 15;
2823                break;
2824
2825        case REQUEST_SENSE:
2826                cmdLen = 6;
2827                CDB[0] = cmd;
2828                CDB[4] = io->size;
2829                dir = MPI_SCSIIO_CONTROL_READ;
2830                timeout = 10;
2831                break;
2832
2833        case READ_BUFFER:
2834                cmdLen = 10;
2835                dir = MPI_SCSIIO_CONTROL_READ;
2836                CDB[0] = cmd;
2837                if (io->flags & MPT_ICFLAG_ECHO) {
2838                        CDB[1] = 0x0A;
2839                } else {
2840                        CDB[1] = 0x02;
2841                }
2842
2843                if (io->flags & MPT_ICFLAG_BUF_CAP) {
2844                        CDB[1] |= 0x01;
2845                }
2846                CDB[6] = (io->size >> 16) & 0xFF;
2847                CDB[7] = (io->size >>  8) & 0xFF;
2848                CDB[8] = io->size & 0xFF;
2849                timeout = 10;
2850                break;
2851
2852        case WRITE_BUFFER:
2853                cmdLen = 10;
2854                dir = MPI_SCSIIO_CONTROL_WRITE;
2855                CDB[0] = cmd;
2856                if (io->flags & MPT_ICFLAG_ECHO) {
2857                        CDB[1] = 0x0A;
2858                } else {
2859                        CDB[1] = 0x02;
2860                }
2861                CDB[6] = (io->size >> 16) & 0xFF;
2862                CDB[7] = (io->size >>  8) & 0xFF;
2863                CDB[8] = io->size & 0xFF;
2864                timeout = 10;
2865                break;
2866
2867        case RESERVE:
2868                cmdLen = 6;
2869                dir = MPI_SCSIIO_CONTROL_READ;
2870                CDB[0] = cmd;
2871                timeout = 10;
2872                break;
2873
2874        case RELEASE:
2875                cmdLen = 6;
2876                dir = MPI_SCSIIO_CONTROL_READ;
2877                CDB[0] = cmd;
2878                timeout = 10;
2879                break;
2880
2881        case SYNCHRONIZE_CACHE:
2882                cmdLen = 10;
2883                dir = MPI_SCSIIO_CONTROL_READ;
2884                CDB[0] = cmd;
2885//              CDB[1] = 0x02;  /* set immediate bit */
2886                timeout = 10;
2887                break;
2888
2889        default:
2890                /* Error Case */
2891                ret = -EFAULT;
2892                goto out;
2893        }
2894
2895        /* Get and Populate a free Frame
2896         * MsgContext set in mpt_get_msg_frame call
2897         */
2898        if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
2899                dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
2900                    ioc->name, __func__));
2901                ret = MPT_SCANDV_BUSY;
2902                goto out;
2903        }
2904
2905        pScsiReq = (SCSIIORequest_t *) mf;
2906
2907        /* Get the request index */
2908        my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2909        ADD_INDEX_LOG(my_idx); /* for debug */
2910
2911        if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2912                pScsiReq->TargetID = io->physDiskNum;
2913                pScsiReq->Bus = 0;
2914                pScsiReq->ChainOffset = 0;
2915                pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2916        } else {
2917                pScsiReq->TargetID = io->id;
2918                pScsiReq->Bus = io->channel;
2919                pScsiReq->ChainOffset = 0;
2920                pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2921        }
2922
2923        pScsiReq->CDBLength = cmdLen;
2924        pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2925
2926        pScsiReq->Reserved = 0;
2927
2928        pScsiReq->MsgFlags = mpt_msg_flags(ioc);
2929        /* MsgContext set in mpt_get_msg_fram call  */
2930
2931        int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
2932
2933        if (io->flags & MPT_ICFLAG_TAGGED_CMD)
2934                pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
2935        else
2936                pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2937
2938        if (cmd == REQUEST_SENSE) {
2939                pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2940                devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2941                    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
2942        }
2943
2944        for (ii = 0; ii < 16; ii++)
2945                pScsiReq->CDB[ii] = CDB[ii];
2946
2947        pScsiReq->DataLength = cpu_to_le32(io->size);
2948        pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
2949                                           + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2950
2951        devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2952            "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
2953            ioc->name, __func__, cmd, io->channel, io->id, io->lun));
2954
2955        if (dir == MPI_SCSIIO_CONTROL_READ)
2956                ioc->add_sge((char *) &pScsiReq->SGL,
2957                    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
2958        else
2959                ioc->add_sge((char *) &pScsiReq->SGL,
2960                    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
2961
2962        INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
2963        mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
2964        timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
2965            timeout*HZ);
2966        if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2967                ret = MPT_SCANDV_DID_RESET;
2968                dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2969                    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
2970                    cmd));
2971                if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2972                        mpt_free_msg_frame(ioc, mf);
2973                        goto out;
2974                }
2975                if (!timeleft) {
2976                        printk(MYIOC_s_WARN_FMT
2977                               "Issuing Reset from %s!! doorbell=0x%08xh"
2978                               " cmd=0x%02x\n",
2979                               ioc->name, __func__, mpt_GetIocState(ioc, 0),
2980                               cmd);
2981                        mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2982                        mpt_free_msg_frame(ioc, mf);
2983                }
2984                goto out;
2985        }
2986
2987        ret = ioc->internal_cmds.completion_code;
2988        devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
2989                        ioc->name, __func__, ret));
2990
2991 out:
2992        CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
2993        mutex_unlock(&ioc->internal_cmds.mutex);
2994        return ret;
2995}
2996
2997/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2998/**
2999 *      mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3000 *      @hd: Pointer to a SCSI HOST structure
3001 *      @vdevice: virtual target device
3002 *
3003 *      Uses the ISR, but with special processing.
3004 *      MUST be single-threaded.
3005 *
3006 */
3007static void
3008mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3009{
3010        INTERNAL_CMD             iocmd;
3011
3012        /* Ignore hidden raid components, this is handled when the command
3013         * is sent to the volume
3014         */
3015        if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3016                return;
3017
3018        if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3019            !vdevice->configured_lun)
3020                return;
3021
3022        /* Following parameters will not change
3023         * in this routine.
3024         */
3025        iocmd.cmd = SYNCHRONIZE_CACHE;
3026        iocmd.flags = 0;
3027        iocmd.physDiskNum = -1;
3028        iocmd.data = NULL;
3029        iocmd.data_dma = -1;
3030        iocmd.size = 0;
3031        iocmd.rsvd = iocmd.rsvd2 = 0;
3032        iocmd.channel = vdevice->vtarget->channel;
3033        iocmd.id = vdevice->vtarget->id;
3034        iocmd.lun = vdevice->lun;
3035
3036        mptscsih_do_cmd(hd, &iocmd);
3037}
3038
3039static ssize_t
3040mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3041                         char *buf)
3042{
3043        struct Scsi_Host *host = class_to_shost(dev);
3044        MPT_SCSI_HOST   *hd = shost_priv(host);
3045        MPT_ADAPTER *ioc = hd->ioc;
3046
3047        return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3048            (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3049            (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3050            (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3051            ioc->facts.FWVersion.Word & 0x000000FF);
3052}
3053static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3054
3055static ssize_t
3056mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3057                           char *buf)
3058{
3059        struct Scsi_Host *host = class_to_shost(dev);
3060        MPT_SCSI_HOST   *hd = shost_priv(host);
3061        MPT_ADAPTER *ioc = hd->ioc;
3062
3063        return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3064            (ioc->biosVersion & 0xFF000000) >> 24,
3065            (ioc->biosVersion & 0x00FF0000) >> 16,
3066            (ioc->biosVersion & 0x0000FF00) >> 8,
3067            ioc->biosVersion & 0x000000FF);
3068}
3069static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3070
3071static ssize_t
3072mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3073                          char *buf)
3074{
3075        struct Scsi_Host *host = class_to_shost(dev);
3076        MPT_SCSI_HOST   *hd = shost_priv(host);
3077        MPT_ADAPTER *ioc = hd->ioc;
3078
3079        return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3080}
3081static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3082
3083static ssize_t
3084mptscsih_version_product_show(struct device *dev,
3085                              struct device_attribute *attr,
3086char *buf)
3087{
3088        struct Scsi_Host *host = class_to_shost(dev);
3089        MPT_SCSI_HOST   *hd = shost_priv(host);
3090        MPT_ADAPTER *ioc = hd->ioc;
3091
3092        return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3093}
3094static DEVICE_ATTR(version_product, S_IRUGO,
3095    mptscsih_version_product_show, NULL);
3096
3097static ssize_t
3098mptscsih_version_nvdata_persistent_show(struct device *dev,
3099                                        struct device_attribute *attr,
3100                                        char *buf)
3101{
3102        struct Scsi_Host *host = class_to_shost(dev);
3103        MPT_SCSI_HOST   *hd = shost_priv(host);
3104        MPT_ADAPTER *ioc = hd->ioc;
3105
3106        return snprintf(buf, PAGE_SIZE, "%02xh\n",
3107            ioc->nvdata_version_persistent);
3108}
3109static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3110    mptscsih_version_nvdata_persistent_show, NULL);
3111
3112static ssize_t
3113mptscsih_version_nvdata_default_show(struct device *dev,
3114                                     struct device_attribute *attr, char *buf)
3115{
3116        struct Scsi_Host *host = class_to_shost(dev);
3117        MPT_SCSI_HOST   *hd = shost_priv(host);
3118        MPT_ADAPTER *ioc = hd->ioc;
3119
3120        return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3121}
3122static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3123    mptscsih_version_nvdata_default_show, NULL);
3124
3125static ssize_t
3126mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3127                         char *buf)
3128{
3129        struct Scsi_Host *host = class_to_shost(dev);
3130        MPT_SCSI_HOST   *hd = shost_priv(host);
3131        MPT_ADAPTER *ioc = hd->ioc;
3132
3133        return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3134}
3135static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3136
3137static ssize_t
3138mptscsih_board_assembly_show(struct device *dev,
3139                             struct device_attribute *attr, char *buf)
3140{
3141        struct Scsi_Host *host = class_to_shost(dev);
3142        MPT_SCSI_HOST   *hd = shost_priv(host);
3143        MPT_ADAPTER *ioc = hd->ioc;
3144
3145        return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3146}
3147static DEVICE_ATTR(board_assembly, S_IRUGO,
3148    mptscsih_board_assembly_show, NULL);
3149
3150static ssize_t
3151mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3152                           char *buf)
3153{
3154        struct Scsi_Host *host = class_to_shost(dev);
3155        MPT_SCSI_HOST   *hd = shost_priv(host);
3156        MPT_ADAPTER *ioc = hd->ioc;
3157
3158        return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3159}
3160static DEVICE_ATTR(board_tracer, S_IRUGO,
3161    mptscsih_board_tracer_show, NULL);
3162
3163static ssize_t
3164mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3165                       char *buf)
3166{
3167        struct Scsi_Host *host = class_to_shost(dev);
3168        MPT_SCSI_HOST   *hd = shost_priv(host);
3169        MPT_ADAPTER *ioc = hd->ioc;
3170
3171        return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3172}
3173static DEVICE_ATTR(io_delay, S_IRUGO,
3174    mptscsih_io_delay_show, NULL);
3175
3176static ssize_t
3177mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
3178                           char *buf)
3179{
3180        struct Scsi_Host *host = class_to_shost(dev);
3181        MPT_SCSI_HOST   *hd = shost_priv(host);
3182        MPT_ADAPTER *ioc = hd->ioc;
3183
3184        return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3185}
3186static DEVICE_ATTR(device_delay, S_IRUGO,
3187    mptscsih_device_delay_show, NULL);
3188
3189static ssize_t
3190mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3191                          char *buf)
3192{
3193        struct Scsi_Host *host = class_to_shost(dev);
3194        MPT_SCSI_HOST   *hd = shost_priv(host);
3195        MPT_ADAPTER *ioc = hd->ioc;
3196
3197        return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3198}
3199static ssize_t
3200mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3201                           const char *buf, size_t count)
3202{
3203        struct Scsi_Host *host = class_to_shost(dev);
3204        MPT_SCSI_HOST   *hd = shost_priv(host);
3205        MPT_ADAPTER *ioc = hd->ioc;
3206        int val = 0;
3207
3208        if (sscanf(buf, "%x", &val) != 1)
3209                return -EINVAL;
3210
3211        ioc->debug_level = val;
3212        printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3213                                ioc->name, ioc->debug_level);
3214        return strlen(buf);
3215}
3216static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3217        mptscsih_debug_level_show, mptscsih_debug_level_store);
3218
3219struct device_attribute *mptscsih_host_attrs[] = {
3220        &dev_attr_version_fw,
3221        &dev_attr_version_bios,
3222        &dev_attr_version_mpi,
3223        &dev_attr_version_product,
3224        &dev_attr_version_nvdata_persistent,
3225        &dev_attr_version_nvdata_default,
3226        &dev_attr_board_name,
3227        &dev_attr_board_assembly,
3228        &dev_attr_board_tracer,
3229        &dev_attr_io_delay,
3230        &dev_attr_device_delay,
3231        &dev_attr_debug_level,
3232        NULL,
3233};
3234
3235EXPORT_SYMBOL(mptscsih_host_attrs);
3236
3237EXPORT_SYMBOL(mptscsih_remove);
3238EXPORT_SYMBOL(mptscsih_shutdown);
3239#ifdef CONFIG_PM
3240EXPORT_SYMBOL(mptscsih_suspend);
3241EXPORT_SYMBOL(mptscsih_resume);
3242#endif
3243EXPORT_SYMBOL(mptscsih_show_info);
3244EXPORT_SYMBOL(mptscsih_info);
3245EXPORT_SYMBOL(mptscsih_qcmd);
3246EXPORT_SYMBOL(mptscsih_slave_destroy);
3247EXPORT_SYMBOL(mptscsih_slave_configure);
3248EXPORT_SYMBOL(mptscsih_abort);
3249EXPORT_SYMBOL(mptscsih_dev_reset);
3250EXPORT_SYMBOL(mptscsih_bus_reset);
3251EXPORT_SYMBOL(mptscsih_host_reset);
3252EXPORT_SYMBOL(mptscsih_bios_param);
3253EXPORT_SYMBOL(mptscsih_io_done);
3254EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3255EXPORT_SYMBOL(mptscsih_scandv_complete);
3256EXPORT_SYMBOL(mptscsih_event_process);
3257EXPORT_SYMBOL(mptscsih_ioc_reset);
3258EXPORT_SYMBOL(mptscsih_change_queue_depth);
3259
3260/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3261