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