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