linux/drivers/message/fusion/mptbase.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/message/fusion/mptbase.c
   3 *      This is the Fusion MPT base driver which supports multiple
   4 *      (SCSI + LAN) specialized protocol drivers.
   5 *      For use with LSI PCI chip/adapter(s)
   6 *      running LSI Fusion MPT (Message Passing Technology) firmware.
   7 *
   8 *  Copyright (c) 1999-2008 LSI Corporation
   9 *  (mailto:DL-MPTFusionLinux@lsi.com)
  10 *
  11 */
  12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  13/*
  14    This program is free software; you can redistribute it and/or modify
  15    it under the terms of the GNU General Public License as published by
  16    the Free Software Foundation; version 2 of the License.
  17
  18    This program is distributed in the hope that it will be useful,
  19    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21    GNU General Public License for more details.
  22
  23    NO WARRANTY
  24    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  25    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  26    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  27    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  28    solely responsible for determining the appropriateness of using and
  29    distributing the Program and assumes all risks associated with its
  30    exercise of rights under this Agreement, including but not limited to
  31    the risks and costs of program errors, damage to or loss of data,
  32    programs or equipment, and unavailability or interruption of operations.
  33
  34    DISCLAIMER OF LIABILITY
  35    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  36    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  38    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  39    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  40    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  41    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  42
  43    You should have received a copy of the GNU General Public License
  44    along with this program; if not, write to the Free Software
  45    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  46*/
  47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  48
  49#include <linux/kernel.h>
  50#include <linux/module.h>
  51#include <linux/errno.h>
  52#include <linux/init.h>
  53#include <linux/seq_file.h>
  54#include <linux/slab.h>
  55#include <linux/types.h>
  56#include <linux/pci.h>
  57#include <linux/kdev_t.h>
  58#include <linux/blkdev.h>
  59#include <linux/delay.h>
  60#include <linux/interrupt.h>            /* needed for in_interrupt() proto */
  61#include <linux/dma-mapping.h>
  62#include <asm/io.h>
  63#ifdef CONFIG_MTRR
  64#include <asm/mtrr.h>
  65#endif
  66
  67#include "mptbase.h"
  68#include "lsi/mpi_log_fc.h"
  69
  70/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  71#define my_NAME         "Fusion MPT base driver"
  72#define my_VERSION      MPT_LINUX_VERSION_COMMON
  73#define MYNAM           "mptbase"
  74
  75MODULE_AUTHOR(MODULEAUTHOR);
  76MODULE_DESCRIPTION(my_NAME);
  77MODULE_LICENSE("GPL");
  78MODULE_VERSION(my_VERSION);
  79
  80/*
  81 *  cmd line parameters
  82 */
  83
  84static int mpt_msi_enable_spi;
  85module_param(mpt_msi_enable_spi, int, 0);
  86MODULE_PARM_DESC(mpt_msi_enable_spi,
  87                 " Enable MSI Support for SPI controllers (default=0)");
  88
  89static int mpt_msi_enable_fc;
  90module_param(mpt_msi_enable_fc, int, 0);
  91MODULE_PARM_DESC(mpt_msi_enable_fc,
  92                 " Enable MSI Support for FC controllers (default=0)");
  93
  94static int mpt_msi_enable_sas;
  95module_param(mpt_msi_enable_sas, int, 0);
  96MODULE_PARM_DESC(mpt_msi_enable_sas,
  97                 " Enable MSI Support for SAS controllers (default=0)");
  98
  99static int mpt_channel_mapping;
 100module_param(mpt_channel_mapping, int, 0);
 101MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
 102
 103static int mpt_debug_level;
 104static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
 105module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
 106                  &mpt_debug_level, 0600);
 107MODULE_PARM_DESC(mpt_debug_level,
 108                 " debug level - refer to mptdebug.h - (default=0)");
 109
 110int mpt_fwfault_debug;
 111EXPORT_SYMBOL(mpt_fwfault_debug);
 112module_param(mpt_fwfault_debug, int, 0600);
 113MODULE_PARM_DESC(mpt_fwfault_debug,
 114                 "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
 115
 116static char     MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS][50];
 117
 118#ifdef MFCNT
 119static int mfcounter = 0;
 120#define PRINT_MF_COUNT 20000
 121#endif
 122
 123/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 124/*
 125 *  Public data...
 126 */
 127
 128#define WHOINIT_UNKNOWN         0xAA
 129
 130/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 131/*
 132 *  Private data...
 133 */
 134                                        /* Adapter link list */
 135LIST_HEAD(ioc_list);
 136                                        /* Callback lookup table */
 137static MPT_CALLBACK              MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
 138                                        /* Protocol driver class lookup table */
 139static int                       MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
 140                                        /* Event handler lookup table */
 141static MPT_EVHANDLER             MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 142                                        /* Reset handler lookup table */
 143static MPT_RESETHANDLER          MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 144static struct mpt_pci_driver    *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 145
 146#ifdef CONFIG_PROC_FS
 147static struct proc_dir_entry    *mpt_proc_root_dir;
 148#endif
 149
 150/*
 151 *  Driver Callback Index's
 152 */
 153static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
 154static u8 last_drv_idx;
 155
 156/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 157/*
 158 *  Forward protos...
 159 */
 160static irqreturn_t mpt_interrupt(int irq, void *bus_id);
 161static int      mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
 162                MPT_FRAME_HDR *reply);
 163static int      mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
 164                        u32 *req, int replyBytes, u16 *u16reply, int maxwait,
 165                        int sleepFlag);
 166static int      mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
 167static void     mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
 168static void     mpt_adapter_disable(MPT_ADAPTER *ioc);
 169static void     mpt_adapter_dispose(MPT_ADAPTER *ioc);
 170
 171static void     MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
 172static int      MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
 173static int      GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
 174static int      GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
 175static int      SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
 176static int      SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
 177static int      mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
 178static int      mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
 179static int      mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
 180static int      KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
 181static int      SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
 182static int      PrimeIocFifos(MPT_ADAPTER *ioc);
 183static int      WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
 184static int      WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
 185static int      WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
 186static int      GetLanConfigPages(MPT_ADAPTER *ioc);
 187static int      GetIoUnitPage2(MPT_ADAPTER *ioc);
 188int             mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
 189static int      mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
 190static int      mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
 191static void     mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
 192static void     mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
 193static void     mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
 194static int      SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
 195        int sleepFlag);
 196static int      SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
 197static int      mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
 198static int      mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
 199
 200#ifdef CONFIG_PROC_FS
 201static const struct file_operations mpt_summary_proc_fops;
 202static const struct file_operations mpt_version_proc_fops;
 203static const struct file_operations mpt_iocinfo_proc_fops;
 204#endif
 205static void     mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
 206
 207static int      ProcessEventNotification(MPT_ADAPTER *ioc,
 208                EventNotificationReply_t *evReply, int *evHandlers);
 209static void     mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
 210static void     mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
 211static void     mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
 212static void     mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
 213static int      mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
 214static void     mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
 215
 216/* module entry point */
 217static int  __init    fusion_init  (void);
 218static void __exit    fusion_exit  (void);
 219
 220#define CHIPREG_READ32(addr)            readl_relaxed(addr)
 221#define CHIPREG_READ32_dmasync(addr)    readl(addr)
 222#define CHIPREG_WRITE32(addr,val)       writel(val, addr)
 223#define CHIPREG_PIO_WRITE32(addr,val)   outl(val, (unsigned long)addr)
 224#define CHIPREG_PIO_READ32(addr)        inl((unsigned long)addr)
 225
 226static void
 227pci_disable_io_access(struct pci_dev *pdev)
 228{
 229        u16 command_reg;
 230
 231        pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
 232        command_reg &= ~1;
 233        pci_write_config_word(pdev, PCI_COMMAND, command_reg);
 234}
 235
 236static void
 237pci_enable_io_access(struct pci_dev *pdev)
 238{
 239        u16 command_reg;
 240
 241        pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
 242        command_reg |= 1;
 243        pci_write_config_word(pdev, PCI_COMMAND, command_reg);
 244}
 245
 246static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
 247{
 248        int ret = param_set_int(val, kp);
 249        MPT_ADAPTER *ioc;
 250
 251        if (ret)
 252                return ret;
 253
 254        list_for_each_entry(ioc, &ioc_list, list)
 255                ioc->debug_level = mpt_debug_level;
 256        return 0;
 257}
 258
 259/**
 260 *      mpt_get_cb_idx - obtain cb_idx for registered driver
 261 *      @dclass: class driver enum
 262 *
 263 *      Returns cb_idx, or zero means it wasn't found
 264 **/
 265static u8
 266mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
 267{
 268        u8 cb_idx;
 269
 270        for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
 271                if (MptDriverClass[cb_idx] == dclass)
 272                        return cb_idx;
 273        return 0;
 274}
 275
 276/**
 277 * mpt_is_discovery_complete - determine if discovery has completed
 278 * @ioc: per adatper instance
 279 *
 280 * Returns 1 when discovery completed, else zero.
 281 */
 282static int
 283mpt_is_discovery_complete(MPT_ADAPTER *ioc)
 284{
 285        ConfigExtendedPageHeader_t hdr;
 286        CONFIGPARMS cfg;
 287        SasIOUnitPage0_t *buffer;
 288        dma_addr_t dma_handle;
 289        int rc = 0;
 290
 291        memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
 292        memset(&cfg, 0, sizeof(CONFIGPARMS));
 293        hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
 294        hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
 295        hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
 296        cfg.cfghdr.ehdr = &hdr;
 297        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 298
 299        if ((mpt_config(ioc, &cfg)))
 300                goto out;
 301        if (!hdr.ExtPageLength)
 302                goto out;
 303
 304        buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
 305            &dma_handle);
 306        if (!buffer)
 307                goto out;
 308
 309        cfg.physAddr = dma_handle;
 310        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
 311
 312        if ((mpt_config(ioc, &cfg)))
 313                goto out_free_consistent;
 314
 315        if (!(buffer->PhyData[0].PortFlags &
 316            MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
 317                rc = 1;
 318
 319 out_free_consistent:
 320        pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
 321            buffer, dma_handle);
 322 out:
 323        return rc;
 324}
 325
 326/**
 327 *      mpt_fault_reset_work - work performed on workq after ioc fault
 328 *      @work: input argument, used to derive ioc
 329 *
 330**/
 331static void
 332mpt_fault_reset_work(struct work_struct *work)
 333{
 334        MPT_ADAPTER     *ioc =
 335            container_of(work, MPT_ADAPTER, fault_reset_work.work);
 336        u32              ioc_raw_state;
 337        int              rc;
 338        unsigned long    flags;
 339
 340        if (ioc->ioc_reset_in_progress || !ioc->active)
 341                goto out;
 342
 343        ioc_raw_state = mpt_GetIocState(ioc, 0);
 344        if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
 345                printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
 346                       ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
 347                printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
 348                       ioc->name, __func__);
 349                rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
 350                printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
 351                       __func__, (rc == 0) ? "success" : "failed");
 352                ioc_raw_state = mpt_GetIocState(ioc, 0);
 353                if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
 354                        printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
 355                            "reset (%04xh)\n", ioc->name, ioc_raw_state &
 356                            MPI_DOORBELL_DATA_MASK);
 357        } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
 358                if ((mpt_is_discovery_complete(ioc))) {
 359                        devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
 360                            "discovery_quiesce_io flag\n", ioc->name));
 361                        ioc->sas_discovery_quiesce_io = 0;
 362                }
 363        }
 364
 365 out:
 366        /*
 367         * Take turns polling alternate controller
 368         */
 369        if (ioc->alt_ioc)
 370                ioc = ioc->alt_ioc;
 371
 372        /* rearm the timer */
 373        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
 374        if (ioc->reset_work_q)
 375                queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
 376                        msecs_to_jiffies(MPT_POLLING_INTERVAL));
 377        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
 378}
 379
 380
 381/*
 382 *  Process turbo (context) reply...
 383 */
 384static void
 385mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
 386{
 387        MPT_FRAME_HDR *mf = NULL;
 388        MPT_FRAME_HDR *mr = NULL;
 389        u16 req_idx = 0;
 390        u8 cb_idx;
 391
 392        dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
 393                                ioc->name, pa));
 394
 395        switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
 396        case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
 397                req_idx = pa & 0x0000FFFF;
 398                cb_idx = (pa & 0x00FF0000) >> 16;
 399                mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
 400                break;
 401        case MPI_CONTEXT_REPLY_TYPE_LAN:
 402                cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
 403                /*
 404                 *  Blind set of mf to NULL here was fatal
 405                 *  after lan_reply says "freeme"
 406                 *  Fix sort of combined with an optimization here;
 407                 *  added explicit check for case where lan_reply
 408                 *  was just returning 1 and doing nothing else.
 409                 *  For this case skip the callback, but set up
 410                 *  proper mf value first here:-)
 411                 */
 412                if ((pa & 0x58000000) == 0x58000000) {
 413                        req_idx = pa & 0x0000FFFF;
 414                        mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
 415                        mpt_free_msg_frame(ioc, mf);
 416                        mb();
 417                        return;
 418                        break;
 419                }
 420                mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
 421                break;
 422        case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
 423                cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
 424                mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
 425                break;
 426        default:
 427                cb_idx = 0;
 428                BUG();
 429        }
 430
 431        /*  Check for (valid) IO callback!  */
 432        if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
 433                MptCallbacks[cb_idx] == NULL) {
 434                printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
 435                                __func__, ioc->name, cb_idx);
 436                goto out;
 437        }
 438
 439        if (MptCallbacks[cb_idx](ioc, mf, mr))
 440                mpt_free_msg_frame(ioc, mf);
 441 out:
 442        mb();
 443}
 444
 445static void
 446mpt_reply(MPT_ADAPTER *ioc, u32 pa)
 447{
 448        MPT_FRAME_HDR   *mf;
 449        MPT_FRAME_HDR   *mr;
 450        u16              req_idx;
 451        u8               cb_idx;
 452        int              freeme;
 453
 454        u32 reply_dma_low;
 455        u16 ioc_stat;
 456
 457        /* non-TURBO reply!  Hmmm, something may be up...
 458         *  Newest turbo reply mechanism; get address
 459         *  via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
 460         */
 461
 462        /* Map DMA address of reply header to cpu address.
 463         * pa is 32 bits - but the dma address may be 32 or 64 bits
 464         * get offset based only only the low addresses
 465         */
 466
 467        reply_dma_low = (pa <<= 1);
 468        mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
 469                         (reply_dma_low - ioc->reply_frames_low_dma));
 470
 471        req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
 472        cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
 473        mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
 474
 475        dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
 476                        ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
 477        DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
 478
 479         /*  Check/log IOC log info
 480         */
 481        ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
 482        if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
 483                u32      log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
 484                if (ioc->bus_type == FC)
 485                        mpt_fc_log_info(ioc, log_info);
 486                else if (ioc->bus_type == SPI)
 487                        mpt_spi_log_info(ioc, log_info);
 488                else if (ioc->bus_type == SAS)
 489                        mpt_sas_log_info(ioc, log_info, cb_idx);
 490        }
 491
 492        if (ioc_stat & MPI_IOCSTATUS_MASK)
 493                mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
 494
 495        /*  Check for (valid) IO callback!  */
 496        if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
 497                MptCallbacks[cb_idx] == NULL) {
 498                printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
 499                                __func__, ioc->name, cb_idx);
 500                freeme = 0;
 501                goto out;
 502        }
 503
 504        freeme = MptCallbacks[cb_idx](ioc, mf, mr);
 505
 506 out:
 507        /*  Flush (non-TURBO) reply with a WRITE!  */
 508        CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
 509
 510        if (freeme)
 511                mpt_free_msg_frame(ioc, mf);
 512        mb();
 513}
 514
 515/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 516/**
 517 *      mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
 518 *      @irq: irq number (not used)
 519 *      @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
 520 *
 521 *      This routine is registered via the request_irq() kernel API call,
 522 *      and handles all interrupts generated from a specific MPT adapter
 523 *      (also referred to as a IO Controller or IOC).
 524 *      This routine must clear the interrupt from the adapter and does
 525 *      so by reading the reply FIFO.  Multiple replies may be processed
 526 *      per single call to this routine.
 527 *
 528 *      This routine handles register-level access of the adapter but
 529 *      dispatches (calls) a protocol-specific callback routine to handle
 530 *      the protocol-specific details of the MPT request completion.
 531 */
 532static irqreturn_t
 533mpt_interrupt(int irq, void *bus_id)
 534{
 535        MPT_ADAPTER *ioc = bus_id;
 536        u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
 537
 538        if (pa == 0xFFFFFFFF)
 539                return IRQ_NONE;
 540
 541        /*
 542         *  Drain the reply FIFO!
 543         */
 544        do {
 545                if (pa & MPI_ADDRESS_REPLY_A_BIT)
 546                        mpt_reply(ioc, pa);
 547                else
 548                        mpt_turbo_reply(ioc, pa);
 549                pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
 550        } while (pa != 0xFFFFFFFF);
 551
 552        return IRQ_HANDLED;
 553}
 554
 555/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 556/**
 557 *      mptbase_reply - MPT base driver's callback routine
 558 *      @ioc: Pointer to MPT_ADAPTER structure
 559 *      @req: Pointer to original MPT request frame
 560 *      @reply: Pointer to MPT reply frame (NULL if TurboReply)
 561 *
 562 *      MPT base driver's callback routine; all base driver
 563 *      "internal" request/reply processing is routed here.
 564 *      Currently used for EventNotification and EventAck handling.
 565 *
 566 *      Returns 1 indicating original alloc'd request frame ptr
 567 *      should be freed, or 0 if it shouldn't.
 568 */
 569static int
 570mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
 571{
 572        EventNotificationReply_t *pEventReply;
 573        u8 event;
 574        int evHandlers;
 575        int freereq = 1;
 576
 577        switch (reply->u.hdr.Function) {
 578        case MPI_FUNCTION_EVENT_NOTIFICATION:
 579                pEventReply = (EventNotificationReply_t *)reply;
 580                evHandlers = 0;
 581                ProcessEventNotification(ioc, pEventReply, &evHandlers);
 582                event = le32_to_cpu(pEventReply->Event) & 0xFF;
 583                if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
 584                        freereq = 0;
 585                if (event != MPI_EVENT_EVENT_CHANGE)
 586                        break;
 587        case MPI_FUNCTION_CONFIG:
 588        case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
 589                ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
 590                if (reply) {
 591                        ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
 592                        memcpy(ioc->mptbase_cmds.reply, reply,
 593                            min(MPT_DEFAULT_FRAME_SIZE,
 594                                4 * reply->u.reply.MsgLength));
 595                }
 596                if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
 597                        ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
 598                        complete(&ioc->mptbase_cmds.done);
 599                } else
 600                        freereq = 0;
 601                if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
 602                        freereq = 1;
 603                break;
 604        case MPI_FUNCTION_EVENT_ACK:
 605                devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 606                    "EventAck reply received\n", ioc->name));
 607                break;
 608        default:
 609                printk(MYIOC_s_ERR_FMT
 610                    "Unexpected msg function (=%02Xh) reply received!\n",
 611                    ioc->name, reply->u.hdr.Function);
 612                break;
 613        }
 614
 615        /*
 616         *      Conditionally tell caller to free the original
 617         *      EventNotification/EventAck/unexpected request frame!
 618         */
 619        return freereq;
 620}
 621
 622/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 623/**
 624 *      mpt_register - Register protocol-specific main callback handler.
 625 *      @cbfunc: callback function pointer
 626 *      @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
 627 *      @func_name: call function's name
 628 *
 629 *      This routine is called by a protocol-specific driver (SCSI host,
 630 *      LAN, SCSI target) to register its reply callback routine.  Each
 631 *      protocol-specific driver must do this before it will be able to
 632 *      use any IOC resources, such as obtaining request frames.
 633 *
 634 *      NOTES: The SCSI protocol driver currently calls this routine thrice
 635 *      in order to register separate callbacks; one for "normal" SCSI IO;
 636 *      one for MptScsiTaskMgmt requests; one for Scan/DV requests.
 637 *
 638 *      Returns u8 valued "handle" in the range (and S.O.D. order)
 639 *      {N,...,7,6,5,...,1} if successful.
 640 *      A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
 641 *      considered an error by the caller.
 642 */
 643u8
 644mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
 645{
 646        u8 cb_idx;
 647        last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
 648
 649        /*
 650         *  Search for empty callback slot in this order: {N,...,7,6,5,...,1}
 651         *  (slot/handle 0 is reserved!)
 652         */
 653        for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
 654                if (MptCallbacks[cb_idx] == NULL) {
 655                        MptCallbacks[cb_idx] = cbfunc;
 656                        MptDriverClass[cb_idx] = dclass;
 657                        MptEvHandlers[cb_idx] = NULL;
 658                        last_drv_idx = cb_idx;
 659                        memcpy(MptCallbacksName[cb_idx], func_name,
 660                            strlen(func_name) > 50 ? 50 : strlen(func_name));
 661                        break;
 662                }
 663        }
 664
 665        return last_drv_idx;
 666}
 667
 668/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 669/**
 670 *      mpt_deregister - Deregister a protocol drivers resources.
 671 *      @cb_idx: previously registered callback handle
 672 *
 673 *      Each protocol-specific driver should call this routine when its
 674 *      module is unloaded.
 675 */
 676void
 677mpt_deregister(u8 cb_idx)
 678{
 679        if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
 680                MptCallbacks[cb_idx] = NULL;
 681                MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
 682                MptEvHandlers[cb_idx] = NULL;
 683
 684                last_drv_idx++;
 685        }
 686}
 687
 688/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 689/**
 690 *      mpt_event_register - Register protocol-specific event callback handler.
 691 *      @cb_idx: previously registered (via mpt_register) callback handle
 692 *      @ev_cbfunc: callback function
 693 *
 694 *      This routine can be called by one or more protocol-specific drivers
 695 *      if/when they choose to be notified of MPT events.
 696 *
 697 *      Returns 0 for success.
 698 */
 699int
 700mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
 701{
 702        if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 703                return -1;
 704
 705        MptEvHandlers[cb_idx] = ev_cbfunc;
 706        return 0;
 707}
 708
 709/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 710/**
 711 *      mpt_event_deregister - Deregister protocol-specific event callback handler
 712 *      @cb_idx: previously registered callback handle
 713 *
 714 *      Each protocol-specific driver should call this routine
 715 *      when it does not (or can no longer) handle events,
 716 *      or when its module is unloaded.
 717 */
 718void
 719mpt_event_deregister(u8 cb_idx)
 720{
 721        if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 722                return;
 723
 724        MptEvHandlers[cb_idx] = NULL;
 725}
 726
 727/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 728/**
 729 *      mpt_reset_register - Register protocol-specific IOC reset handler.
 730 *      @cb_idx: previously registered (via mpt_register) callback handle
 731 *      @reset_func: reset function
 732 *
 733 *      This routine can be called by one or more protocol-specific drivers
 734 *      if/when they choose to be notified of IOC resets.
 735 *
 736 *      Returns 0 for success.
 737 */
 738int
 739mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
 740{
 741        if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 742                return -1;
 743
 744        MptResetHandlers[cb_idx] = reset_func;
 745        return 0;
 746}
 747
 748/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 749/**
 750 *      mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
 751 *      @cb_idx: previously registered callback handle
 752 *
 753 *      Each protocol-specific driver should call this routine
 754 *      when it does not (or can no longer) handle IOC reset handling,
 755 *      or when its module is unloaded.
 756 */
 757void
 758mpt_reset_deregister(u8 cb_idx)
 759{
 760        if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 761                return;
 762
 763        MptResetHandlers[cb_idx] = NULL;
 764}
 765
 766/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 767/**
 768 *      mpt_device_driver_register - Register device driver hooks
 769 *      @dd_cbfunc: driver callbacks struct
 770 *      @cb_idx: MPT protocol driver index
 771 */
 772int
 773mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
 774{
 775        MPT_ADAPTER     *ioc;
 776        const struct pci_device_id *id;
 777
 778        if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 779                return -EINVAL;
 780
 781        MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
 782
 783        /* call per pci device probe entry point */
 784        list_for_each_entry(ioc, &ioc_list, list) {
 785                id = ioc->pcidev->driver ?
 786                    ioc->pcidev->driver->id_table : NULL;
 787                if (dd_cbfunc->probe)
 788                        dd_cbfunc->probe(ioc->pcidev, id);
 789         }
 790
 791        return 0;
 792}
 793
 794/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 795/**
 796 *      mpt_device_driver_deregister - DeRegister device driver hooks
 797 *      @cb_idx: MPT protocol driver index
 798 */
 799void
 800mpt_device_driver_deregister(u8 cb_idx)
 801{
 802        struct mpt_pci_driver *dd_cbfunc;
 803        MPT_ADAPTER     *ioc;
 804
 805        if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 806                return;
 807
 808        dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
 809
 810        list_for_each_entry(ioc, &ioc_list, list) {
 811                if (dd_cbfunc->remove)
 812                        dd_cbfunc->remove(ioc->pcidev);
 813        }
 814
 815        MptDeviceDriverHandlers[cb_idx] = NULL;
 816}
 817
 818
 819/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 820/**
 821 *      mpt_get_msg_frame - Obtain an MPT request frame from the pool
 822 *      @cb_idx: Handle of registered MPT protocol driver
 823 *      @ioc: Pointer to MPT adapter structure
 824 *
 825 *      Obtain an MPT request frame from the pool (of 1024) that are
 826 *      allocated per MPT adapter.
 827 *
 828 *      Returns pointer to a MPT request frame or %NULL if none are available
 829 *      or IOC is not active.
 830 */
 831MPT_FRAME_HDR*
 832mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
 833{
 834        MPT_FRAME_HDR *mf;
 835        unsigned long flags;
 836        u16      req_idx;       /* Request index */
 837
 838        /* validate handle and ioc identifier */
 839
 840#ifdef MFCNT
 841        if (!ioc->active)
 842                printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
 843                    "returning NULL!\n", ioc->name);
 844#endif
 845
 846        /* If interrupts are not attached, do not return a request frame */
 847        if (!ioc->active)
 848                return NULL;
 849
 850        spin_lock_irqsave(&ioc->FreeQlock, flags);
 851        if (!list_empty(&ioc->FreeQ)) {
 852                int req_offset;
 853
 854                mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
 855                                u.frame.linkage.list);
 856                list_del(&mf->u.frame.linkage.list);
 857                mf->u.frame.linkage.arg1 = 0;
 858                mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;  /* byte */
 859                req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
 860                                                                /* u16! */
 861                req_idx = req_offset / ioc->req_sz;
 862                mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
 863                mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
 864                /* Default, will be changed if necessary in SG generation */
 865                ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
 866#ifdef MFCNT
 867                ioc->mfcnt++;
 868#endif
 869        }
 870        else
 871                mf = NULL;
 872        spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 873
 874#ifdef MFCNT
 875        if (mf == NULL)
 876                printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
 877                    "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
 878                    ioc->req_depth);
 879        mfcounter++;
 880        if (mfcounter == PRINT_MF_COUNT)
 881                printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
 882                    ioc->mfcnt, ioc->req_depth);
 883#endif
 884
 885        dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
 886            ioc->name, cb_idx, ioc->id, mf));
 887        return mf;
 888}
 889
 890/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 891/**
 892 *      mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
 893 *      @cb_idx: Handle of registered MPT protocol driver
 894 *      @ioc: Pointer to MPT adapter structure
 895 *      @mf: Pointer to MPT request frame
 896 *
 897 *      This routine posts an MPT request frame to the request post FIFO of a
 898 *      specific MPT adapter.
 899 */
 900void
 901mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
 902{
 903        u32 mf_dma_addr;
 904        int req_offset;
 905        u16      req_idx;       /* Request index */
 906
 907        /* ensure values are reset properly! */
 908        mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;          /* byte */
 909        req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
 910                                                                /* u16! */
 911        req_idx = req_offset / ioc->req_sz;
 912        mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
 913        mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
 914
 915        DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
 916
 917        mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
 918        dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
 919            "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
 920            ioc->RequestNB[req_idx]));
 921        CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
 922}
 923
 924/**
 925 *      mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
 926 *      @cb_idx: Handle of registered MPT protocol driver
 927 *      @ioc: Pointer to MPT adapter structure
 928 *      @mf: Pointer to MPT request frame
 929 *
 930 *      Send a protocol-specific MPT request frame to an IOC using
 931 *      hi-priority request queue.
 932 *
 933 *      This routine posts an MPT request frame to the request post FIFO of a
 934 *      specific MPT adapter.
 935 **/
 936void
 937mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
 938{
 939        u32 mf_dma_addr;
 940        int req_offset;
 941        u16      req_idx;       /* Request index */
 942
 943        /* ensure values are reset properly! */
 944        mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
 945        req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
 946        req_idx = req_offset / ioc->req_sz;
 947        mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
 948        mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
 949
 950        DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
 951
 952        mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
 953        dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
 954                ioc->name, mf_dma_addr, req_idx));
 955        CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
 956}
 957
 958/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 959/**
 960 *      mpt_free_msg_frame - Place MPT request frame back on FreeQ.
 961 *      @ioc: Pointer to MPT adapter structure
 962 *      @mf: Pointer to MPT request frame
 963 *
 964 *      This routine places a MPT request frame back on the MPT adapter's
 965 *      FreeQ.
 966 */
 967void
 968mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
 969{
 970        unsigned long flags;
 971
 972        /*  Put Request back on FreeQ!  */
 973        spin_lock_irqsave(&ioc->FreeQlock, flags);
 974        if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
 975                goto out;
 976        /* signature to know if this mf is freed */
 977        mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
 978        list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
 979#ifdef MFCNT
 980        ioc->mfcnt--;
 981#endif
 982 out:
 983        spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 984}
 985
 986/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 987/**
 988 *      mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
 989 *      @pAddr: virtual address for SGE
 990 *      @flagslength: SGE flags and data transfer length
 991 *      @dma_addr: Physical address
 992 *
 993 *      This routine places a MPT request frame back on the MPT adapter's
 994 *      FreeQ.
 995 */
 996static void
 997mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
 998{
 999        SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1000        pSge->FlagsLength = cpu_to_le32(flagslength);
1001        pSge->Address = cpu_to_le32(dma_addr);
1002}
1003
1004/**
1005 *      mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1006 *      @pAddr: virtual address for SGE
1007 *      @flagslength: SGE flags and data transfer length
1008 *      @dma_addr: Physical address
1009 *
1010 *      This routine places a MPT request frame back on the MPT adapter's
1011 *      FreeQ.
1012 **/
1013static void
1014mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1015{
1016        SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1017        pSge->Address.Low = cpu_to_le32
1018                        (lower_32_bits(dma_addr));
1019        pSge->Address.High = cpu_to_le32
1020                        (upper_32_bits(dma_addr));
1021        pSge->FlagsLength = cpu_to_le32
1022                        ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1023}
1024
1025/**
1026 *      mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1027 *      @pAddr: virtual address for SGE
1028 *      @flagslength: SGE flags and data transfer length
1029 *      @dma_addr: Physical address
1030 *
1031 *      This routine places a MPT request frame back on the MPT adapter's
1032 *      FreeQ.
1033 **/
1034static void
1035mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1036{
1037        SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1038        u32 tmp;
1039
1040        pSge->Address.Low = cpu_to_le32
1041                        (lower_32_bits(dma_addr));
1042        tmp = (u32)(upper_32_bits(dma_addr));
1043
1044        /*
1045         * 1078 errata workaround for the 36GB limitation
1046         */
1047        if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32)  == 9) {
1048                flagslength |=
1049                    MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1050                tmp |= (1<<31);
1051                if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1052                        printk(KERN_DEBUG "1078 P0M2 addressing for "
1053                            "addr = 0x%llx len = %d\n",
1054                            (unsigned long long)dma_addr,
1055                            MPI_SGE_LENGTH(flagslength));
1056        }
1057
1058        pSge->Address.High = cpu_to_le32(tmp);
1059        pSge->FlagsLength = cpu_to_le32(
1060                (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1061}
1062
1063/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1064/**
1065 *      mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1066 *      @pAddr: virtual address for SGE
1067 *      @next: nextChainOffset value (u32's)
1068 *      @length: length of next SGL segment
1069 *      @dma_addr: Physical address
1070 *
1071 */
1072static void
1073mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1074{
1075                SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1076                pChain->Length = cpu_to_le16(length);
1077                pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1078                pChain->NextChainOffset = next;
1079                pChain->Address = cpu_to_le32(dma_addr);
1080}
1081
1082/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1083/**
1084 *      mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1085 *      @pAddr: virtual address for SGE
1086 *      @next: nextChainOffset value (u32's)
1087 *      @length: length of next SGL segment
1088 *      @dma_addr: Physical address
1089 *
1090 */
1091static void
1092mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1093{
1094                SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1095                u32 tmp = dma_addr & 0xFFFFFFFF;
1096
1097                pChain->Length = cpu_to_le16(length);
1098                pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1099                                 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1100
1101                pChain->NextChainOffset = next;
1102
1103                pChain->Address.Low = cpu_to_le32(tmp);
1104                tmp = (u32)(upper_32_bits(dma_addr));
1105                pChain->Address.High = cpu_to_le32(tmp);
1106}
1107
1108/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1109/**
1110 *      mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1111 *      @cb_idx: Handle of registered MPT protocol driver
1112 *      @ioc: Pointer to MPT adapter structure
1113 *      @reqBytes: Size of the request in bytes
1114 *      @req: Pointer to MPT request frame
1115 *      @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1116 *
1117 *      This routine is used exclusively to send MptScsiTaskMgmt
1118 *      requests since they are required to be sent via doorbell handshake.
1119 *
1120 *      NOTE: It is the callers responsibility to byte-swap fields in the
1121 *      request which are greater than 1 byte in size.
1122 *
1123 *      Returns 0 for success, non-zero for failure.
1124 */
1125int
1126mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1127{
1128        int     r = 0;
1129        u8      *req_as_bytes;
1130        int      ii;
1131
1132        /* State is known to be good upon entering
1133         * this function so issue the bus reset
1134         * request.
1135         */
1136
1137        /*
1138         * Emulate what mpt_put_msg_frame() does /wrt to sanity
1139         * setting cb_idx/req_idx.  But ONLY if this request
1140         * is in proper (pre-alloc'd) request buffer range...
1141         */
1142        ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1143        if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1144                MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1145                mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1146                mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1147        }
1148
1149        /* Make sure there are no doorbells */
1150        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1151
1152        CHIPREG_WRITE32(&ioc->chip->Doorbell,
1153                        ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1154                         ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1155
1156        /* Wait for IOC doorbell int */
1157        if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1158                return ii;
1159        }
1160
1161        /* Read doorbell and check for active bit */
1162        if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1163                return -5;
1164
1165        dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1166                ioc->name, ii));
1167
1168        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1169
1170        if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1171                return -2;
1172        }
1173
1174        /* Send request via doorbell handshake */
1175        req_as_bytes = (u8 *) req;
1176        for (ii = 0; ii < reqBytes/4; ii++) {
1177                u32 word;
1178
1179                word = ((req_as_bytes[(ii*4) + 0] <<  0) |
1180                        (req_as_bytes[(ii*4) + 1] <<  8) |
1181                        (req_as_bytes[(ii*4) + 2] << 16) |
1182                        (req_as_bytes[(ii*4) + 3] << 24));
1183                CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1184                if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1185                        r = -3;
1186                        break;
1187                }
1188        }
1189
1190        if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1191                r = 0;
1192        else
1193                r = -4;
1194
1195        /* Make sure there are no doorbells */
1196        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1197
1198        return r;
1199}
1200
1201/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1202/**
1203 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1204 * @ioc: Pointer to MPT adapter structure
1205 * @access_control_value: define bits below
1206 * @sleepFlag: Specifies whether the process can sleep
1207 *
1208 * Provides mechanism for the host driver to control the IOC's
1209 * Host Page Buffer access.
1210 *
1211 * Access Control Value - bits[15:12]
1212 * 0h Reserved
1213 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1214 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1215 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1216 *
1217 * Returns 0 for success, non-zero for failure.
1218 */
1219
1220static int
1221mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1222{
1223        int      r = 0;
1224
1225        /* return if in use */
1226        if (CHIPREG_READ32(&ioc->chip->Doorbell)
1227            & MPI_DOORBELL_ACTIVE)
1228            return -1;
1229
1230        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1231
1232        CHIPREG_WRITE32(&ioc->chip->Doorbell,
1233                ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1234                 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1235                 (access_control_value<<12)));
1236
1237        /* Wait for IOC to clear Doorbell Status bit */
1238        if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1239                return -2;
1240        }else
1241                return 0;
1242}
1243
1244/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1245/**
1246 *      mpt_host_page_alloc - allocate system memory for the fw
1247 *      @ioc: Pointer to pointer to IOC adapter
1248 *      @ioc_init: Pointer to ioc init config page
1249 *
1250 *      If we already allocated memory in past, then resend the same pointer.
1251 *      Returns 0 for success, non-zero for failure.
1252 */
1253static int
1254mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1255{
1256        char    *psge;
1257        int     flags_length;
1258        u32     host_page_buffer_sz=0;
1259
1260        if(!ioc->HostPageBuffer) {
1261
1262                host_page_buffer_sz =
1263                    le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1264
1265                if(!host_page_buffer_sz)
1266                        return 0; /* fw doesn't need any host buffers */
1267
1268                /* spin till we get enough memory */
1269                while(host_page_buffer_sz > 0) {
1270
1271                        if((ioc->HostPageBuffer = pci_alloc_consistent(
1272                            ioc->pcidev,
1273                            host_page_buffer_sz,
1274                            &ioc->HostPageBuffer_dma)) != NULL) {
1275
1276                                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1277                                    "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1278                                    ioc->name, ioc->HostPageBuffer,
1279                                    (u32)ioc->HostPageBuffer_dma,
1280                                    host_page_buffer_sz));
1281                                ioc->alloc_total += host_page_buffer_sz;
1282                                ioc->HostPageBuffer_sz = host_page_buffer_sz;
1283                                break;
1284                        }
1285
1286                        host_page_buffer_sz -= (4*1024);
1287                }
1288        }
1289
1290        if(!ioc->HostPageBuffer) {
1291                printk(MYIOC_s_ERR_FMT
1292                    "Failed to alloc memory for host_page_buffer!\n",
1293                    ioc->name);
1294                return -999;
1295        }
1296
1297        psge = (char *)&ioc_init->HostPageBufferSGE;
1298        flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1299            MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1300            MPI_SGE_FLAGS_HOST_TO_IOC |
1301            MPI_SGE_FLAGS_END_OF_BUFFER;
1302        flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1303        flags_length |= ioc->HostPageBuffer_sz;
1304        ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1305        ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1306
1307return 0;
1308}
1309
1310/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1311/**
1312 *      mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1313 *      @iocid: IOC unique identifier (integer)
1314 *      @iocpp: Pointer to pointer to IOC adapter
1315 *
1316 *      Given a unique IOC identifier, set pointer to the associated MPT
1317 *      adapter structure.
1318 *
1319 *      Returns iocid and sets iocpp if iocid is found.
1320 *      Returns -1 if iocid is not found.
1321 */
1322int
1323mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1324{
1325        MPT_ADAPTER *ioc;
1326
1327        list_for_each_entry(ioc,&ioc_list,list) {
1328                if (ioc->id == iocid) {
1329                        *iocpp =ioc;
1330                        return iocid;
1331                }
1332        }
1333
1334        *iocpp = NULL;
1335        return -1;
1336}
1337
1338/**
1339 *      mpt_get_product_name - returns product string
1340 *      @vendor: pci vendor id
1341 *      @device: pci device id
1342 *      @revision: pci revision id
1343 *      @prod_name: string returned
1344 *
1345 *      Returns product string displayed when driver loads,
1346 *      in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1347 *
1348 **/
1349static void
1350mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1351{
1352        char *product_str = NULL;
1353
1354        if (vendor == PCI_VENDOR_ID_BROCADE) {
1355                switch (device)
1356                {
1357                case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1358                        switch (revision)
1359                        {
1360                        case 0x00:
1361                                product_str = "BRE040 A0";
1362                                break;
1363                        case 0x01:
1364                                product_str = "BRE040 A1";
1365                                break;
1366                        default:
1367                                product_str = "BRE040";
1368                                break;
1369                        }
1370                        break;
1371                }
1372                goto out;
1373        }
1374
1375        switch (device)
1376        {
1377        case MPI_MANUFACTPAGE_DEVICEID_FC909:
1378                product_str = "LSIFC909 B1";
1379                break;
1380        case MPI_MANUFACTPAGE_DEVICEID_FC919:
1381                product_str = "LSIFC919 B0";
1382                break;
1383        case MPI_MANUFACTPAGE_DEVICEID_FC929:
1384                product_str = "LSIFC929 B0";
1385                break;
1386        case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1387                if (revision < 0x80)
1388                        product_str = "LSIFC919X A0";
1389                else
1390                        product_str = "LSIFC919XL A1";
1391                break;
1392        case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1393                if (revision < 0x80)
1394                        product_str = "LSIFC929X A0";
1395                else
1396                        product_str = "LSIFC929XL A1";
1397                break;
1398        case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1399                product_str = "LSIFC939X A1";
1400                break;
1401        case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1402                product_str = "LSIFC949X A1";
1403                break;
1404        case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1405                switch (revision)
1406                {
1407                case 0x00:
1408                        product_str = "LSIFC949E A0";
1409                        break;
1410                case 0x01:
1411                        product_str = "LSIFC949E A1";
1412                        break;
1413                default:
1414                        product_str = "LSIFC949E";
1415                        break;
1416                }
1417                break;
1418        case MPI_MANUFACTPAGE_DEVID_53C1030:
1419                switch (revision)
1420                {
1421                case 0x00:
1422                        product_str = "LSI53C1030 A0";
1423                        break;
1424                case 0x01:
1425                        product_str = "LSI53C1030 B0";
1426                        break;
1427                case 0x03:
1428                        product_str = "LSI53C1030 B1";
1429                        break;
1430                case 0x07:
1431                        product_str = "LSI53C1030 B2";
1432                        break;
1433                case 0x08:
1434                        product_str = "LSI53C1030 C0";
1435                        break;
1436                case 0x80:
1437                        product_str = "LSI53C1030T A0";
1438                        break;
1439                case 0x83:
1440                        product_str = "LSI53C1030T A2";
1441                        break;
1442                case 0x87:
1443                        product_str = "LSI53C1030T A3";
1444                        break;
1445                case 0xc1:
1446                        product_str = "LSI53C1020A A1";
1447                        break;
1448                default:
1449                        product_str = "LSI53C1030";
1450                        break;
1451                }
1452                break;
1453        case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1454                switch (revision)
1455                {
1456                case 0x03:
1457                        product_str = "LSI53C1035 A2";
1458                        break;
1459                case 0x04:
1460                        product_str = "LSI53C1035 B0";
1461                        break;
1462                default:
1463                        product_str = "LSI53C1035";
1464                        break;
1465                }
1466                break;
1467        case MPI_MANUFACTPAGE_DEVID_SAS1064:
1468                switch (revision)
1469                {
1470                case 0x00:
1471                        product_str = "LSISAS1064 A1";
1472                        break;
1473                case 0x01:
1474                        product_str = "LSISAS1064 A2";
1475                        break;
1476                case 0x02:
1477                        product_str = "LSISAS1064 A3";
1478                        break;
1479                case 0x03:
1480                        product_str = "LSISAS1064 A4";
1481                        break;
1482                default:
1483                        product_str = "LSISAS1064";
1484                        break;
1485                }
1486                break;
1487        case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1488                switch (revision)
1489                {
1490                case 0x00:
1491                        product_str = "LSISAS1064E A0";
1492                        break;
1493                case 0x01:
1494                        product_str = "LSISAS1064E B0";
1495                        break;
1496                case 0x02:
1497                        product_str = "LSISAS1064E B1";
1498                        break;
1499                case 0x04:
1500                        product_str = "LSISAS1064E B2";
1501                        break;
1502                case 0x08:
1503                        product_str = "LSISAS1064E B3";
1504                        break;
1505                default:
1506                        product_str = "LSISAS1064E";
1507                        break;
1508                }
1509                break;
1510        case MPI_MANUFACTPAGE_DEVID_SAS1068:
1511                switch (revision)
1512                {
1513                case 0x00:
1514                        product_str = "LSISAS1068 A0";
1515                        break;
1516                case 0x01:
1517                        product_str = "LSISAS1068 B0";
1518                        break;
1519                case 0x02:
1520                        product_str = "LSISAS1068 B1";
1521                        break;
1522                default:
1523                        product_str = "LSISAS1068";
1524                        break;
1525                }
1526                break;
1527        case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1528                switch (revision)
1529                {
1530                case 0x00:
1531                        product_str = "LSISAS1068E A0";
1532                        break;
1533                case 0x01:
1534                        product_str = "LSISAS1068E B0";
1535                        break;
1536                case 0x02:
1537                        product_str = "LSISAS1068E B1";
1538                        break;
1539                case 0x04:
1540                        product_str = "LSISAS1068E B2";
1541                        break;
1542                case 0x08:
1543                        product_str = "LSISAS1068E B3";
1544                        break;
1545                default:
1546                        product_str = "LSISAS1068E";
1547                        break;
1548                }
1549                break;
1550        case MPI_MANUFACTPAGE_DEVID_SAS1078:
1551                switch (revision)
1552                {
1553                case 0x00:
1554                        product_str = "LSISAS1078 A0";
1555                        break;
1556                case 0x01:
1557                        product_str = "LSISAS1078 B0";
1558                        break;
1559                case 0x02:
1560                        product_str = "LSISAS1078 C0";
1561                        break;
1562                case 0x03:
1563                        product_str = "LSISAS1078 C1";
1564                        break;
1565                case 0x04:
1566                        product_str = "LSISAS1078 C2";
1567                        break;
1568                default:
1569                        product_str = "LSISAS1078";
1570                        break;
1571                }
1572                break;
1573        }
1574
1575 out:
1576        if (product_str)
1577                sprintf(prod_name, "%s", product_str);
1578}
1579
1580/**
1581 *      mpt_mapresources - map in memory mapped io
1582 *      @ioc: Pointer to pointer to IOC adapter
1583 *
1584 **/
1585static int
1586mpt_mapresources(MPT_ADAPTER *ioc)
1587{
1588        u8              __iomem *mem;
1589        int              ii;
1590        resource_size_t  mem_phys;
1591        unsigned long    port;
1592        u32              msize;
1593        u32              psize;
1594        u8               revision;
1595        int              r = -ENODEV;
1596        struct pci_dev *pdev;
1597
1598        pdev = ioc->pcidev;
1599        ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1600        if (pci_enable_device_mem(pdev)) {
1601                printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1602                    "failed\n", ioc->name);
1603                return r;
1604        }
1605        if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1606                printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1607                    "MEM failed\n", ioc->name);
1608                return r;
1609        }
1610
1611        pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1612
1613        if (sizeof(dma_addr_t) > 4) {
1614                const uint64_t required_mask = dma_get_required_mask
1615                    (&pdev->dev);
1616                if (required_mask > DMA_BIT_MASK(32)
1617                        && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1618                        && !pci_set_consistent_dma_mask(pdev,
1619                                                 DMA_BIT_MASK(64))) {
1620                        ioc->dma_mask = DMA_BIT_MASK(64);
1621                        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1622                                ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1623                                ioc->name));
1624                } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1625                        && !pci_set_consistent_dma_mask(pdev,
1626                                                DMA_BIT_MASK(32))) {
1627                        ioc->dma_mask = DMA_BIT_MASK(32);
1628                        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1629                                ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1630                                ioc->name));
1631                } else {
1632                        printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1633                            ioc->name, pci_name(pdev));
1634                        pci_release_selected_regions(pdev, ioc->bars);
1635                        return r;
1636                }
1637        } else {
1638                if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1639                        && !pci_set_consistent_dma_mask(pdev,
1640                                                DMA_BIT_MASK(32))) {
1641                        ioc->dma_mask = DMA_BIT_MASK(32);
1642                        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1643                                ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1644                                ioc->name));
1645                } else {
1646                        printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1647                            ioc->name, pci_name(pdev));
1648                        pci_release_selected_regions(pdev, ioc->bars);
1649                        return r;
1650                }
1651        }
1652
1653        mem_phys = msize = 0;
1654        port = psize = 0;
1655        for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1656                if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1657                        if (psize)
1658                                continue;
1659                        /* Get I/O space! */
1660                        port = pci_resource_start(pdev, ii);
1661                        psize = pci_resource_len(pdev, ii);
1662                } else {
1663                        if (msize)
1664                                continue;
1665                        /* Get memmap */
1666                        mem_phys = pci_resource_start(pdev, ii);
1667                        msize = pci_resource_len(pdev, ii);
1668                }
1669        }
1670        ioc->mem_size = msize;
1671
1672        mem = NULL;
1673        /* Get logical ptr for PciMem0 space */
1674        /*mem = ioremap(mem_phys, msize);*/
1675        mem = ioremap(mem_phys, msize);
1676        if (mem == NULL) {
1677                printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1678                        " memory!\n", ioc->name);
1679                pci_release_selected_regions(pdev, ioc->bars);
1680                return -EINVAL;
1681        }
1682        ioc->memmap = mem;
1683        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1684            ioc->name, mem, (unsigned long long)mem_phys));
1685
1686        ioc->mem_phys = mem_phys;
1687        ioc->chip = (SYSIF_REGS __iomem *)mem;
1688
1689        /* Save Port IO values in case we need to do downloadboot */
1690        ioc->pio_mem_phys = port;
1691        ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1692
1693        return 0;
1694}
1695
1696/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1697/**
1698 *      mpt_attach - Install a PCI intelligent MPT adapter.
1699 *      @pdev: Pointer to pci_dev structure
1700 *      @id: PCI device ID information
1701 *
1702 *      This routine performs all the steps necessary to bring the IOC of
1703 *      a MPT adapter to a OPERATIONAL state.  This includes registering
1704 *      memory regions, registering the interrupt, and allocating request
1705 *      and reply memory pools.
1706 *
1707 *      This routine also pre-fetches the LAN MAC address of a Fibre Channel
1708 *      MPT adapter.
1709 *
1710 *      Returns 0 for success, non-zero for failure.
1711 *
1712 *      TODO: Add support for polled controllers
1713 */
1714int
1715mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1716{
1717        MPT_ADAPTER     *ioc;
1718        u8               cb_idx;
1719        int              r = -ENODEV;
1720        u8               revision;
1721        u8               pcixcmd;
1722        static int       mpt_ids = 0;
1723#ifdef CONFIG_PROC_FS
1724        struct proc_dir_entry *dent;
1725#endif
1726
1727        ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1728        if (ioc == NULL) {
1729                printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1730                return -ENOMEM;
1731        }
1732
1733        ioc->id = mpt_ids++;
1734        sprintf(ioc->name, "ioc%d", ioc->id);
1735        dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1736
1737        /*
1738         * set initial debug level
1739         * (refer to mptdebug.h)
1740         *
1741         */
1742        ioc->debug_level = mpt_debug_level;
1743        if (mpt_debug_level)
1744                printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1745
1746        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1747
1748        ioc->pcidev = pdev;
1749        if (mpt_mapresources(ioc)) {
1750                kfree(ioc);
1751                return r;
1752        }
1753
1754        /*
1755         * Setting up proper handlers for scatter gather handling
1756         */
1757        if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1758                if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1759                        ioc->add_sge = &mpt_add_sge_64bit_1078;
1760                else
1761                        ioc->add_sge = &mpt_add_sge_64bit;
1762                ioc->add_chain = &mpt_add_chain_64bit;
1763                ioc->sg_addr_size = 8;
1764        } else {
1765                ioc->add_sge = &mpt_add_sge;
1766                ioc->add_chain = &mpt_add_chain;
1767                ioc->sg_addr_size = 4;
1768        }
1769        ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1770
1771        ioc->alloc_total = sizeof(MPT_ADAPTER);
1772        ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;           /* avoid div by zero! */
1773        ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1774
1775
1776        spin_lock_init(&ioc->taskmgmt_lock);
1777        mutex_init(&ioc->internal_cmds.mutex);
1778        init_completion(&ioc->internal_cmds.done);
1779        mutex_init(&ioc->mptbase_cmds.mutex);
1780        init_completion(&ioc->mptbase_cmds.done);
1781        mutex_init(&ioc->taskmgmt_cmds.mutex);
1782        init_completion(&ioc->taskmgmt_cmds.done);
1783
1784        /* Initialize the event logging.
1785         */
1786        ioc->eventTypes = 0;    /* None */
1787        ioc->eventContext = 0;
1788        ioc->eventLogSize = 0;
1789        ioc->events = NULL;
1790
1791#ifdef MFCNT
1792        ioc->mfcnt = 0;
1793#endif
1794
1795        ioc->sh = NULL;
1796        ioc->cached_fw = NULL;
1797
1798        /* Initialize SCSI Config Data structure
1799         */
1800        memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1801
1802        /* Initialize the fc rport list head.
1803         */
1804        INIT_LIST_HEAD(&ioc->fc_rports);
1805
1806        /* Find lookup slot. */
1807        INIT_LIST_HEAD(&ioc->list);
1808
1809
1810        /* Initialize workqueue */
1811        INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1812
1813        snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1814                 "mpt_poll_%d", ioc->id);
1815        ioc->reset_work_q =
1816                create_singlethread_workqueue(ioc->reset_work_q_name);
1817        if (!ioc->reset_work_q) {
1818                printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1819                    ioc->name);
1820                pci_release_selected_regions(pdev, ioc->bars);
1821                kfree(ioc);
1822                return -ENOMEM;
1823        }
1824
1825        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1826            ioc->name, &ioc->facts, &ioc->pfacts[0]));
1827
1828        pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1829        mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1830
1831        switch (pdev->device)
1832        {
1833        case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1834        case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1835                ioc->errata_flag_1064 = 1;
1836        case MPI_MANUFACTPAGE_DEVICEID_FC909:
1837        case MPI_MANUFACTPAGE_DEVICEID_FC929:
1838        case MPI_MANUFACTPAGE_DEVICEID_FC919:
1839        case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1840                ioc->bus_type = FC;
1841                break;
1842
1843        case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1844                if (revision < XL_929) {
1845                        /* 929X Chip Fix. Set Split transactions level
1846                        * for PCIX. Set MOST bits to zero.
1847                        */
1848                        pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1849                        pcixcmd &= 0x8F;
1850                        pci_write_config_byte(pdev, 0x6a, pcixcmd);
1851                } else {
1852                        /* 929XL Chip Fix. Set MMRBC to 0x08.
1853                        */
1854                        pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1855                        pcixcmd |= 0x08;
1856                        pci_write_config_byte(pdev, 0x6a, pcixcmd);
1857                }
1858                ioc->bus_type = FC;
1859                break;
1860
1861        case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1862                /* 919X Chip Fix. Set Split transactions level
1863                 * for PCIX. Set MOST bits to zero.
1864                 */
1865                pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1866                pcixcmd &= 0x8F;
1867                pci_write_config_byte(pdev, 0x6a, pcixcmd);
1868                ioc->bus_type = FC;
1869                break;
1870
1871        case MPI_MANUFACTPAGE_DEVID_53C1030:
1872                /* 1030 Chip Fix. Disable Split transactions
1873                 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1874                 */
1875                if (revision < C0_1030) {
1876                        pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1877                        pcixcmd &= 0x8F;
1878                        pci_write_config_byte(pdev, 0x6a, pcixcmd);
1879                }
1880
1881        case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1882                ioc->bus_type = SPI;
1883                break;
1884
1885        case MPI_MANUFACTPAGE_DEVID_SAS1064:
1886        case MPI_MANUFACTPAGE_DEVID_SAS1068:
1887                ioc->errata_flag_1064 = 1;
1888                ioc->bus_type = SAS;
1889                break;
1890
1891        case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1892        case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1893        case MPI_MANUFACTPAGE_DEVID_SAS1078:
1894                ioc->bus_type = SAS;
1895                break;
1896        }
1897
1898
1899        switch (ioc->bus_type) {
1900
1901        case SAS:
1902                ioc->msi_enable = mpt_msi_enable_sas;
1903                break;
1904
1905        case SPI:
1906                ioc->msi_enable = mpt_msi_enable_spi;
1907                break;
1908
1909        case FC:
1910                ioc->msi_enable = mpt_msi_enable_fc;
1911                break;
1912
1913        default:
1914                ioc->msi_enable = 0;
1915                break;
1916        }
1917
1918        ioc->fw_events_off = 1;
1919
1920        if (ioc->errata_flag_1064)
1921                pci_disable_io_access(pdev);
1922
1923        spin_lock_init(&ioc->FreeQlock);
1924
1925        /* Disable all! */
1926        CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1927        ioc->active = 0;
1928        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1929
1930        /* Set IOC ptr in the pcidev's driver data. */
1931        pci_set_drvdata(ioc->pcidev, ioc);
1932
1933        /* Set lookup ptr. */
1934        list_add_tail(&ioc->list, &ioc_list);
1935
1936        /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1937         */
1938        mpt_detect_bound_ports(ioc, pdev);
1939
1940        INIT_LIST_HEAD(&ioc->fw_event_list);
1941        spin_lock_init(&ioc->fw_event_lock);
1942        snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1943        ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1944
1945        if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1946            CAN_SLEEP)) != 0){
1947                printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1948                    ioc->name, r);
1949
1950                list_del(&ioc->list);
1951                if (ioc->alt_ioc)
1952                        ioc->alt_ioc->alt_ioc = NULL;
1953                iounmap(ioc->memmap);
1954                if (r != -5)
1955                        pci_release_selected_regions(pdev, ioc->bars);
1956
1957                destroy_workqueue(ioc->reset_work_q);
1958                ioc->reset_work_q = NULL;
1959
1960                kfree(ioc);
1961                pci_set_drvdata(pdev, NULL);
1962                return r;
1963        }
1964
1965        /* call per device driver probe entry point */
1966        for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1967                if(MptDeviceDriverHandlers[cb_idx] &&
1968                  MptDeviceDriverHandlers[cb_idx]->probe) {
1969                        MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1970                }
1971        }
1972
1973#ifdef CONFIG_PROC_FS
1974        /*
1975         *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1976         */
1977        dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1978        if (dent) {
1979                proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc);
1980                proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc);
1981        }
1982#endif
1983
1984        if (!ioc->alt_ioc)
1985                queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1986                        msecs_to_jiffies(MPT_POLLING_INTERVAL));
1987
1988        return 0;
1989}
1990
1991/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1992/**
1993 *      mpt_detach - Remove a PCI intelligent MPT adapter.
1994 *      @pdev: Pointer to pci_dev structure
1995 */
1996
1997void
1998mpt_detach(struct pci_dev *pdev)
1999{
2000        MPT_ADAPTER     *ioc = pci_get_drvdata(pdev);
2001        char pname[32];
2002        u8 cb_idx;
2003        unsigned long flags;
2004        struct workqueue_struct *wq;
2005
2006        /*
2007         * Stop polling ioc for fault condition
2008         */
2009        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2010        wq = ioc->reset_work_q;
2011        ioc->reset_work_q = NULL;
2012        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2013        cancel_delayed_work(&ioc->fault_reset_work);
2014        destroy_workqueue(wq);
2015
2016        spin_lock_irqsave(&ioc->fw_event_lock, flags);
2017        wq = ioc->fw_event_q;
2018        ioc->fw_event_q = NULL;
2019        spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2020        destroy_workqueue(wq);
2021
2022        sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2023        remove_proc_entry(pname, NULL);
2024        sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2025        remove_proc_entry(pname, NULL);
2026        sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2027        remove_proc_entry(pname, NULL);
2028
2029        /* call per device driver remove entry point */
2030        for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2031                if(MptDeviceDriverHandlers[cb_idx] &&
2032                  MptDeviceDriverHandlers[cb_idx]->remove) {
2033                        MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2034                }
2035        }
2036
2037        /* Disable interrupts! */
2038        CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2039
2040        ioc->active = 0;
2041        synchronize_irq(pdev->irq);
2042
2043        /* Clear any lingering interrupt */
2044        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2045
2046        CHIPREG_READ32(&ioc->chip->IntStatus);
2047
2048        mpt_adapter_dispose(ioc);
2049
2050}
2051
2052/**************************************************************************
2053 * Power Management
2054 */
2055#ifdef CONFIG_PM
2056/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2057/**
2058 *      mpt_suspend - Fusion MPT base driver suspend routine.
2059 *      @pdev: Pointer to pci_dev structure
2060 *      @state: new state to enter
2061 */
2062int
2063mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2064{
2065        u32 device_state;
2066        MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2067
2068        device_state = pci_choose_state(pdev, state);
2069        printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2070            "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2071            device_state);
2072
2073        /* put ioc into READY_STATE */
2074        if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2075                printk(MYIOC_s_ERR_FMT
2076                "pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
2077        }
2078
2079        /* disable interrupts */
2080        CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2081        ioc->active = 0;
2082
2083        /* Clear any lingering interrupt */
2084        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2085
2086        free_irq(ioc->pci_irq, ioc);
2087        if (ioc->msi_enable)
2088                pci_disable_msi(ioc->pcidev);
2089        ioc->pci_irq = -1;
2090        pci_save_state(pdev);
2091        pci_disable_device(pdev);
2092        pci_release_selected_regions(pdev, ioc->bars);
2093        pci_set_power_state(pdev, device_state);
2094        return 0;
2095}
2096
2097/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2098/**
2099 *      mpt_resume - Fusion MPT base driver resume routine.
2100 *      @pdev: Pointer to pci_dev structure
2101 */
2102int
2103mpt_resume(struct pci_dev *pdev)
2104{
2105        MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2106        u32 device_state = pdev->current_state;
2107        int recovery_state;
2108        int err;
2109
2110        printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2111            "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2112            device_state);
2113
2114        pci_set_power_state(pdev, PCI_D0);
2115        pci_enable_wake(pdev, PCI_D0, 0);
2116        pci_restore_state(pdev);
2117        ioc->pcidev = pdev;
2118        err = mpt_mapresources(ioc);
2119        if (err)
2120                return err;
2121
2122        if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2123                if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2124                        ioc->add_sge = &mpt_add_sge_64bit_1078;
2125                else
2126                        ioc->add_sge = &mpt_add_sge_64bit;
2127                ioc->add_chain = &mpt_add_chain_64bit;
2128                ioc->sg_addr_size = 8;
2129        } else {
2130
2131                ioc->add_sge = &mpt_add_sge;
2132                ioc->add_chain = &mpt_add_chain;
2133                ioc->sg_addr_size = 4;
2134        }
2135        ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2136
2137        printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2138            ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2139            CHIPREG_READ32(&ioc->chip->Doorbell));
2140
2141        /*
2142         * Errata workaround for SAS pci express:
2143         * Upon returning to the D0 state, the contents of the doorbell will be
2144         * stale data, and this will incorrectly signal to the host driver that
2145         * the firmware is ready to process mpt commands.   The workaround is
2146         * to issue a diagnostic reset.
2147         */
2148        if (ioc->bus_type == SAS && (pdev->device ==
2149            MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2150            MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2151                if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2152                        printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2153                            ioc->name);
2154                        goto out;
2155                }
2156        }
2157
2158        /* bring ioc to operational state */
2159        printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2160        recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2161                                                 CAN_SLEEP);
2162        if (recovery_state != 0)
2163                printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2164                    "error:[%x]\n", ioc->name, recovery_state);
2165        else
2166                printk(MYIOC_s_INFO_FMT
2167                    "pci-resume: success\n", ioc->name);
2168 out:
2169        return 0;
2170
2171}
2172#endif
2173
2174static int
2175mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2176{
2177        if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2178             ioc->bus_type != SPI) ||
2179            (MptDriverClass[index] == MPTFC_DRIVER &&
2180             ioc->bus_type != FC) ||
2181            (MptDriverClass[index] == MPTSAS_DRIVER &&
2182             ioc->bus_type != SAS))
2183                /* make sure we only call the relevant reset handler
2184                 * for the bus */
2185                return 0;
2186        return (MptResetHandlers[index])(ioc, reset_phase);
2187}
2188
2189/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2190/**
2191 *      mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2192 *      @ioc: Pointer to MPT adapter structure
2193 *      @reason: Event word / reason
2194 *      @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2195 *
2196 *      This routine performs all the steps necessary to bring the IOC
2197 *      to a OPERATIONAL state.
2198 *
2199 *      This routine also pre-fetches the LAN MAC address of a Fibre Channel
2200 *      MPT adapter.
2201 *
2202 *      Returns:
2203 *               0 for success
2204 *              -1 if failed to get board READY
2205 *              -2 if READY but IOCFacts Failed
2206 *              -3 if READY but PrimeIOCFifos Failed
2207 *              -4 if READY but IOCInit Failed
2208 *              -5 if failed to enable_device and/or request_selected_regions
2209 *              -6 if failed to upload firmware
2210 */
2211static int
2212mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2213{
2214        int      hard_reset_done = 0;
2215        int      alt_ioc_ready = 0;
2216        int      hard;
2217        int      rc=0;
2218        int      ii;
2219        int      ret = 0;
2220        int      reset_alt_ioc_active = 0;
2221        int      irq_allocated = 0;
2222        u8      *a;
2223
2224        printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2225            reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2226
2227        /* Disable reply interrupts (also blocks FreeQ) */
2228        CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2229        ioc->active = 0;
2230
2231        if (ioc->alt_ioc) {
2232                if (ioc->alt_ioc->active ||
2233                    reason == MPT_HOSTEVENT_IOC_RECOVER) {
2234                        reset_alt_ioc_active = 1;
2235                        /* Disable alt-IOC's reply interrupts
2236                         *  (and FreeQ) for a bit
2237                         **/
2238                        CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2239                                0xFFFFFFFF);
2240                        ioc->alt_ioc->active = 0;
2241                }
2242        }
2243
2244        hard = 1;
2245        if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2246                hard = 0;
2247
2248        if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2249                if (hard_reset_done == -4) {
2250                        printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2251                            ioc->name);
2252
2253                        if (reset_alt_ioc_active && ioc->alt_ioc) {
2254                                /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2255                                dprintk(ioc, printk(MYIOC_s_INFO_FMT
2256                                    "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2257                                CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2258                                ioc->alt_ioc->active = 1;
2259                        }
2260
2261                } else {
2262                        printk(MYIOC_s_WARN_FMT
2263                            "NOT READY WARNING!\n", ioc->name);
2264                }
2265                ret = -1;
2266                goto out;
2267        }
2268
2269        /* hard_reset_done = 0 if a soft reset was performed
2270         * and 1 if a hard reset was performed.
2271         */
2272        if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2273                if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2274                        alt_ioc_ready = 1;
2275                else
2276                        printk(MYIOC_s_WARN_FMT
2277                            ": alt-ioc Not ready WARNING!\n",
2278                            ioc->alt_ioc->name);
2279        }
2280
2281        for (ii=0; ii<5; ii++) {
2282                /* Get IOC facts! Allow 5 retries */
2283                if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2284                        break;
2285        }
2286
2287
2288        if (ii == 5) {
2289                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2290                    "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2291                ret = -2;
2292        } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2293                MptDisplayIocCapabilities(ioc);
2294        }
2295
2296        if (alt_ioc_ready) {
2297                if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2298                        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2299                            "Initial Alt IocFacts failed rc=%x\n",
2300                            ioc->name, rc));
2301                        /* Retry - alt IOC was initialized once
2302                         */
2303                        rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2304                }
2305                if (rc) {
2306                        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2307                            "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2308                        alt_ioc_ready = 0;
2309                        reset_alt_ioc_active = 0;
2310                } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2311                        MptDisplayIocCapabilities(ioc->alt_ioc);
2312                }
2313        }
2314
2315        if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2316            (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2317                pci_release_selected_regions(ioc->pcidev, ioc->bars);
2318                ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2319                    IORESOURCE_IO);
2320                if (pci_enable_device(ioc->pcidev))
2321                        return -5;
2322                if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2323                        "mpt"))
2324                        return -5;
2325        }
2326
2327        /*
2328         * Device is reset now. It must have de-asserted the interrupt line
2329         * (if it was asserted) and it should be safe to register for the
2330         * interrupt now.
2331         */
2332        if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2333                ioc->pci_irq = -1;
2334                if (ioc->pcidev->irq) {
2335                        if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2336                                printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2337                                    ioc->name);
2338                        else
2339                                ioc->msi_enable = 0;
2340                        rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2341                            IRQF_SHARED, ioc->name, ioc);
2342                        if (rc < 0) {
2343                                printk(MYIOC_s_ERR_FMT "Unable to allocate "
2344                                    "interrupt %d!\n",
2345                                    ioc->name, ioc->pcidev->irq);
2346                                if (ioc->msi_enable)
2347                                        pci_disable_msi(ioc->pcidev);
2348                                ret = -EBUSY;
2349                                goto out;
2350                        }
2351                        irq_allocated = 1;
2352                        ioc->pci_irq = ioc->pcidev->irq;
2353                        pci_set_master(ioc->pcidev);            /* ?? */
2354                        pci_set_drvdata(ioc->pcidev, ioc);
2355                        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2356                            "installed at interrupt %d\n", ioc->name,
2357                            ioc->pcidev->irq));
2358                }
2359        }
2360
2361        /* Prime reply & request queues!
2362         * (mucho alloc's) Must be done prior to
2363         * init as upper addresses are needed for init.
2364         * If fails, continue with alt-ioc processing
2365         */
2366        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2367            ioc->name));
2368        if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2369                ret = -3;
2370
2371        /* May need to check/upload firmware & data here!
2372         * If fails, continue with alt-ioc processing
2373         */
2374        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2375            ioc->name));
2376        if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2377                ret = -4;
2378// NEW!
2379        if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2380                printk(MYIOC_s_WARN_FMT
2381                    ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2382                    ioc->alt_ioc->name, rc);
2383                alt_ioc_ready = 0;
2384                reset_alt_ioc_active = 0;
2385        }
2386
2387        if (alt_ioc_ready) {
2388                if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2389                        alt_ioc_ready = 0;
2390                        reset_alt_ioc_active = 0;
2391                        printk(MYIOC_s_WARN_FMT
2392                                ": alt-ioc: (%d) init failure WARNING!\n",
2393                                        ioc->alt_ioc->name, rc);
2394                }
2395        }
2396
2397        if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2398                if (ioc->upload_fw) {
2399                        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2400                            "firmware upload required!\n", ioc->name));
2401
2402                        /* Controller is not operational, cannot do upload
2403                         */
2404                        if (ret == 0) {
2405                                rc = mpt_do_upload(ioc, sleepFlag);
2406                                if (rc == 0) {
2407                                        if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2408                                                /*
2409                                                 * Maintain only one pointer to FW memory
2410                                                 * so there will not be two attempt to
2411                                                 * downloadboot onboard dual function
2412                                                 * chips (mpt_adapter_disable,
2413                                                 * mpt_diag_reset)
2414                                                 */
2415                                                ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2416                                                    "mpt_upload:  alt_%s has cached_fw=%p \n",
2417                                                    ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2418                                                ioc->cached_fw = NULL;
2419                                        }
2420                                } else {
2421                                        printk(MYIOC_s_WARN_FMT
2422                                            "firmware upload failure!\n", ioc->name);
2423                                        ret = -6;
2424                                }
2425                        }
2426                }
2427        }
2428
2429        /*  Enable MPT base driver management of EventNotification
2430         *  and EventAck handling.
2431         */
2432        if ((ret == 0) && (!ioc->facts.EventState)) {
2433                dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2434                        "SendEventNotification\n",
2435                    ioc->name));
2436                ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2437        }
2438
2439        if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2440                rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2441
2442        if (ret == 0) {
2443                /* Enable! (reply interrupt) */
2444                CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2445                ioc->active = 1;
2446        }
2447        if (rc == 0) {  /* alt ioc */
2448                if (reset_alt_ioc_active && ioc->alt_ioc) {
2449                        /* (re)Enable alt-IOC! (reply interrupt) */
2450                        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2451                                "reply irq re-enabled\n",
2452                                ioc->alt_ioc->name));
2453                        CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2454                                MPI_HIM_DIM);
2455                        ioc->alt_ioc->active = 1;
2456                }
2457        }
2458
2459
2460        /*      Add additional "reason" check before call to GetLanConfigPages
2461         *      (combined with GetIoUnitPage2 call).  This prevents a somewhat
2462         *      recursive scenario; GetLanConfigPages times out, timer expired
2463         *      routine calls HardResetHandler, which calls into here again,
2464         *      and we try GetLanConfigPages again...
2465         */
2466        if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2467
2468                /*
2469                 * Initialize link list for inactive raid volumes.
2470                 */
2471                mutex_init(&ioc->raid_data.inactive_list_mutex);
2472                INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2473
2474                switch (ioc->bus_type) {
2475
2476                case SAS:
2477                        /* clear persistency table */
2478                        if(ioc->facts.IOCExceptions &
2479                            MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2480                                ret = mptbase_sas_persist_operation(ioc,
2481                                    MPI_SAS_OP_CLEAR_NOT_PRESENT);
2482                                if(ret != 0)
2483                                        goto out;
2484                        }
2485
2486                        /* Find IM volumes
2487                         */
2488                        mpt_findImVolumes(ioc);
2489
2490                        /* Check, and possibly reset, the coalescing value
2491                         */
2492                        mpt_read_ioc_pg_1(ioc);
2493
2494                        break;
2495
2496                case FC:
2497                        if ((ioc->pfacts[0].ProtocolFlags &
2498                                MPI_PORTFACTS_PROTOCOL_LAN) &&
2499                            (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2500                                /*
2501                                 *  Pre-fetch the ports LAN MAC address!
2502                                 *  (LANPage1_t stuff)
2503                                 */
2504                                (void) GetLanConfigPages(ioc);
2505                                a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2506                                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2507                                        "LanAddr = %02X:%02X:%02X"
2508                                        ":%02X:%02X:%02X\n",
2509                                        ioc->name, a[5], a[4],
2510                                        a[3], a[2], a[1], a[0]));
2511                        }
2512                        break;
2513
2514                case SPI:
2515                        /* Get NVRAM and adapter maximums from SPP 0 and 2
2516                         */
2517                        mpt_GetScsiPortSettings(ioc, 0);
2518
2519                        /* Get version and length of SDP 1
2520                         */
2521                        mpt_readScsiDevicePageHeaders(ioc, 0);
2522
2523                        /* Find IM volumes
2524                         */
2525                        if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2526                                mpt_findImVolumes(ioc);
2527
2528                        /* Check, and possibly reset, the coalescing value
2529                         */
2530                        mpt_read_ioc_pg_1(ioc);
2531
2532                        mpt_read_ioc_pg_4(ioc);
2533
2534                        break;
2535                }
2536
2537                GetIoUnitPage2(ioc);
2538                mpt_get_manufacturing_pg_0(ioc);
2539        }
2540
2541 out:
2542        if ((ret != 0) && irq_allocated) {
2543                free_irq(ioc->pci_irq, ioc);
2544                if (ioc->msi_enable)
2545                        pci_disable_msi(ioc->pcidev);
2546        }
2547        return ret;
2548}
2549
2550/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2551/**
2552 *      mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2553 *      @ioc: Pointer to MPT adapter structure
2554 *      @pdev: Pointer to (struct pci_dev) structure
2555 *
2556 *      Search for PCI bus/dev_function which matches
2557 *      PCI bus/dev_function (+/-1) for newly discovered 929,
2558 *      929X, 1030 or 1035.
2559 *
2560 *      If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2561 *      using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2562 */
2563static void
2564mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2565{
2566        struct pci_dev *peer=NULL;
2567        unsigned int slot = PCI_SLOT(pdev->devfn);
2568        unsigned int func = PCI_FUNC(pdev->devfn);
2569        MPT_ADAPTER *ioc_srch;
2570
2571        dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2572            " searching for devfn match on %x or %x\n",
2573            ioc->name, pci_name(pdev), pdev->bus->number,
2574            pdev->devfn, func-1, func+1));
2575
2576        peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2577        if (!peer) {
2578                peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2579                if (!peer)
2580                        return;
2581        }
2582
2583        list_for_each_entry(ioc_srch, &ioc_list, list) {
2584                struct pci_dev *_pcidev = ioc_srch->pcidev;
2585                if (_pcidev == peer) {
2586                        /* Paranoia checks */
2587                        if (ioc->alt_ioc != NULL) {
2588                                printk(MYIOC_s_WARN_FMT
2589                                    "Oops, already bound (%s <==> %s)!\n",
2590                                    ioc->name, ioc->name, ioc->alt_ioc->name);
2591                                break;
2592                        } else if (ioc_srch->alt_ioc != NULL) {
2593                                printk(MYIOC_s_WARN_FMT
2594                                    "Oops, already bound (%s <==> %s)!\n",
2595                                    ioc_srch->name, ioc_srch->name,
2596                                    ioc_srch->alt_ioc->name);
2597                                break;
2598                        }
2599                        dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2600                                "FOUND! binding %s <==> %s\n",
2601                                ioc->name, ioc->name, ioc_srch->name));
2602                        ioc_srch->alt_ioc = ioc;
2603                        ioc->alt_ioc = ioc_srch;
2604                }
2605        }
2606        pci_dev_put(peer);
2607}
2608
2609/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2610/**
2611 *      mpt_adapter_disable - Disable misbehaving MPT adapter.
2612 *      @ioc: Pointer to MPT adapter structure
2613 */
2614static void
2615mpt_adapter_disable(MPT_ADAPTER *ioc)
2616{
2617        int sz;
2618        int ret;
2619
2620        if (ioc->cached_fw != NULL) {
2621                ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2622                        "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2623                if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2624                    ioc->cached_fw, CAN_SLEEP)) < 0) {
2625                        printk(MYIOC_s_WARN_FMT
2626                            ": firmware downloadboot failure (%d)!\n",
2627                            ioc->name, ret);
2628                }
2629        }
2630
2631        /*
2632         * Put the controller into ready state (if its not already)
2633         */
2634        if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2635                if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2636                    CAN_SLEEP)) {
2637                        if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2638                                printk(MYIOC_s_ERR_FMT "%s:  IOC msg unit "
2639                                    "reset failed to put ioc in ready state!\n",
2640                                    ioc->name, __func__);
2641                } else
2642                        printk(MYIOC_s_ERR_FMT "%s:  IOC msg unit reset "
2643                            "failed!\n", ioc->name, __func__);
2644        }
2645
2646
2647        /* Disable adapter interrupts! */
2648        synchronize_irq(ioc->pcidev->irq);
2649        CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2650        ioc->active = 0;
2651
2652        /* Clear any lingering interrupt */
2653        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2654        CHIPREG_READ32(&ioc->chip->IntStatus);
2655
2656        if (ioc->alloc != NULL) {
2657                sz = ioc->alloc_sz;
2658                dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free  @ %p, sz=%d bytes\n",
2659                    ioc->name, ioc->alloc, ioc->alloc_sz));
2660                pci_free_consistent(ioc->pcidev, sz,
2661                                ioc->alloc, ioc->alloc_dma);
2662                ioc->reply_frames = NULL;
2663                ioc->req_frames = NULL;
2664                ioc->alloc = NULL;
2665                ioc->alloc_total -= sz;
2666        }
2667
2668        if (ioc->sense_buf_pool != NULL) {
2669                sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2670                pci_free_consistent(ioc->pcidev, sz,
2671                                ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2672                ioc->sense_buf_pool = NULL;
2673                ioc->alloc_total -= sz;
2674        }
2675
2676        if (ioc->events != NULL){
2677                sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2678                kfree(ioc->events);
2679                ioc->events = NULL;
2680                ioc->alloc_total -= sz;
2681        }
2682
2683        mpt_free_fw_memory(ioc);
2684
2685        kfree(ioc->spi_data.nvram);
2686        mpt_inactive_raid_list_free(ioc);
2687        kfree(ioc->raid_data.pIocPg2);
2688        kfree(ioc->raid_data.pIocPg3);
2689        ioc->spi_data.nvram = NULL;
2690        ioc->raid_data.pIocPg3 = NULL;
2691
2692        if (ioc->spi_data.pIocPg4 != NULL) {
2693                sz = ioc->spi_data.IocPg4Sz;
2694                pci_free_consistent(ioc->pcidev, sz,
2695                        ioc->spi_data.pIocPg4,
2696                        ioc->spi_data.IocPg4_dma);
2697                ioc->spi_data.pIocPg4 = NULL;
2698                ioc->alloc_total -= sz;
2699        }
2700
2701        if (ioc->ReqToChain != NULL) {
2702                kfree(ioc->ReqToChain);
2703                kfree(ioc->RequestNB);
2704                ioc->ReqToChain = NULL;
2705        }
2706
2707        kfree(ioc->ChainToChain);
2708        ioc->ChainToChain = NULL;
2709
2710        if (ioc->HostPageBuffer != NULL) {
2711                if((ret = mpt_host_page_access_control(ioc,
2712                    MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2713                        printk(MYIOC_s_ERR_FMT
2714                           ": %s: host page buffers free failed (%d)!\n",
2715                            ioc->name, __func__, ret);
2716                }
2717                dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2718                        "HostPageBuffer free  @ %p, sz=%d bytes\n",
2719                        ioc->name, ioc->HostPageBuffer,
2720                        ioc->HostPageBuffer_sz));
2721                pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2722                    ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2723                ioc->HostPageBuffer = NULL;
2724                ioc->HostPageBuffer_sz = 0;
2725                ioc->alloc_total -= ioc->HostPageBuffer_sz;
2726        }
2727
2728        pci_set_drvdata(ioc->pcidev, NULL);
2729}
2730/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2731/**
2732 *      mpt_adapter_dispose - Free all resources associated with an MPT adapter
2733 *      @ioc: Pointer to MPT adapter structure
2734 *
2735 *      This routine unregisters h/w resources and frees all alloc'd memory
2736 *      associated with a MPT adapter structure.
2737 */
2738static void
2739mpt_adapter_dispose(MPT_ADAPTER *ioc)
2740{
2741        int sz_first, sz_last;
2742
2743        if (ioc == NULL)
2744                return;
2745
2746        sz_first = ioc->alloc_total;
2747
2748        mpt_adapter_disable(ioc);
2749
2750        if (ioc->pci_irq != -1) {
2751                free_irq(ioc->pci_irq, ioc);
2752                if (ioc->msi_enable)
2753                        pci_disable_msi(ioc->pcidev);
2754                ioc->pci_irq = -1;
2755        }
2756
2757        if (ioc->memmap != NULL) {
2758                iounmap(ioc->memmap);
2759                ioc->memmap = NULL;
2760        }
2761
2762        pci_disable_device(ioc->pcidev);
2763        pci_release_selected_regions(ioc->pcidev, ioc->bars);
2764
2765#if defined(CONFIG_MTRR) && 0
2766        if (ioc->mtrr_reg > 0) {
2767                mtrr_del(ioc->mtrr_reg, 0, 0);
2768                dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2769        }
2770#endif
2771
2772        /*  Zap the adapter lookup ptr!  */
2773        list_del(&ioc->list);
2774
2775        sz_last = ioc->alloc_total;
2776        dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2777            ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2778
2779        if (ioc->alt_ioc)
2780                ioc->alt_ioc->alt_ioc = NULL;
2781
2782        kfree(ioc);
2783}
2784
2785/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2786/**
2787 *      MptDisplayIocCapabilities - Disply IOC's capabilities.
2788 *      @ioc: Pointer to MPT adapter structure
2789 */
2790static void
2791MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2792{
2793        int i = 0;
2794
2795        printk(KERN_INFO "%s: ", ioc->name);
2796        if (ioc->prod_name)
2797                printk("%s: ", ioc->prod_name);
2798        printk("Capabilities={");
2799
2800        if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2801                printk("Initiator");
2802                i++;
2803        }
2804
2805        if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2806                printk("%sTarget", i ? "," : "");
2807                i++;
2808        }
2809
2810        if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2811                printk("%sLAN", i ? "," : "");
2812                i++;
2813        }
2814
2815#if 0
2816        /*
2817         *  This would probably evoke more questions than it's worth
2818         */
2819        if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2820                printk("%sLogBusAddr", i ? "," : "");
2821                i++;
2822        }
2823#endif
2824
2825        printk("}\n");
2826}
2827
2828/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2829/**
2830 *      MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2831 *      @ioc: Pointer to MPT_ADAPTER structure
2832 *      @force: Force hard KickStart of IOC
2833 *      @sleepFlag: Specifies whether the process can sleep
2834 *
2835 *      Returns:
2836 *               1 - DIAG reset and READY
2837 *               0 - READY initially OR soft reset and READY
2838 *              -1 - Any failure on KickStart
2839 *              -2 - Msg Unit Reset Failed
2840 *              -3 - IO Unit Reset Failed
2841 *              -4 - IOC owned by a PEER
2842 */
2843static int
2844MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2845{
2846        u32      ioc_state;
2847        int      statefault = 0;
2848        int      cntdn;
2849        int      hard_reset_done = 0;
2850        int      r;
2851        int      ii;
2852        int      whoinit;
2853
2854        /* Get current [raw] IOC state  */
2855        ioc_state = mpt_GetIocState(ioc, 0);
2856        dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2857
2858        /*
2859         *      Check to see if IOC got left/stuck in doorbell handshake
2860         *      grip of death.  If so, hard reset the IOC.
2861         */
2862        if (ioc_state & MPI_DOORBELL_ACTIVE) {
2863                statefault = 1;
2864                printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2865                                ioc->name);
2866        }
2867
2868        /* Is it already READY? */
2869        if (!statefault &&
2870            ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2871                dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2872                    "IOC is in READY state\n", ioc->name));
2873                return 0;
2874        }
2875
2876        /*
2877         *      Check to see if IOC is in FAULT state.
2878         */
2879        if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2880                statefault = 2;
2881                printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2882                    ioc->name);
2883                printk(MYIOC_s_WARN_FMT "           FAULT code = %04xh\n",
2884                    ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2885        }
2886
2887        /*
2888         *      Hmmm...  Did it get left operational?
2889         */
2890        if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2891                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2892                                ioc->name));
2893
2894                /* Check WhoInit.
2895                 * If PCI Peer, exit.
2896                 * Else, if no fault conditions are present, issue a MessageUnitReset
2897                 * Else, fall through to KickStart case
2898                 */
2899                whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2900                dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2901                        "whoinit 0x%x statefault %d force %d\n",
2902                        ioc->name, whoinit, statefault, force));
2903                if (whoinit == MPI_WHOINIT_PCI_PEER)
2904                        return -4;
2905                else {
2906                        if ((statefault == 0 ) && (force == 0)) {
2907                                if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2908                                        return 0;
2909                        }
2910                        statefault = 3;
2911                }
2912        }
2913
2914        hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2915        if (hard_reset_done < 0)
2916                return -1;
2917
2918        /*
2919         *  Loop here waiting for IOC to come READY.
2920         */
2921        ii = 0;
2922        cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5;     /* 5 seconds */
2923
2924        while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2925                if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2926                        /*
2927                         *  BIOS or previous driver load left IOC in OP state.
2928                         *  Reset messaging FIFOs.
2929                         */
2930                        if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2931                                printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2932                                return -2;
2933                        }
2934                } else if (ioc_state == MPI_IOC_STATE_RESET) {
2935                        /*
2936                         *  Something is wrong.  Try to get IOC back
2937                         *  to a known state.
2938                         */
2939                        if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2940                                printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2941                                return -3;
2942                        }
2943                }
2944
2945                ii++; cntdn--;
2946                if (!cntdn) {
2947                        printk(MYIOC_s_ERR_FMT
2948                                "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2949                                ioc->name, ioc_state, (int)((ii+5)/HZ));
2950                        return -ETIME;
2951                }
2952
2953                if (sleepFlag == CAN_SLEEP) {
2954                        msleep(1);
2955                } else {
2956                        mdelay (1);     /* 1 msec delay */
2957                }
2958
2959        }
2960
2961        if (statefault < 3) {
2962                printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
2963                        statefault == 1 ? "stuck handshake" : "IOC FAULT");
2964        }
2965
2966        return hard_reset_done;
2967}
2968
2969/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2970/**
2971 *      mpt_GetIocState - Get the current state of a MPT adapter.
2972 *      @ioc: Pointer to MPT_ADAPTER structure
2973 *      @cooked: Request raw or cooked IOC state
2974 *
2975 *      Returns all IOC Doorbell register bits if cooked==0, else just the
2976 *      Doorbell bits in MPI_IOC_STATE_MASK.
2977 */
2978u32
2979mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2980{
2981        u32 s, sc;
2982
2983        /*  Get!  */
2984        s = CHIPREG_READ32(&ioc->chip->Doorbell);
2985        sc = s & MPI_IOC_STATE_MASK;
2986
2987        /*  Save!  */
2988        ioc->last_state = sc;
2989
2990        return cooked ? sc : s;
2991}
2992
2993/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2994/**
2995 *      GetIocFacts - Send IOCFacts request to MPT adapter.
2996 *      @ioc: Pointer to MPT_ADAPTER structure
2997 *      @sleepFlag: Specifies whether the process can sleep
2998 *      @reason: If recovery, only update facts.
2999 *
3000 *      Returns 0 for success, non-zero for failure.
3001 */
3002static int
3003GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3004{
3005        IOCFacts_t               get_facts;
3006        IOCFactsReply_t         *facts;
3007        int                      r;
3008        int                      req_sz;
3009        int                      reply_sz;
3010        int                      sz;
3011        u32                      status, vv;
3012        u8                       shiftFactor=1;
3013
3014        /* IOC *must* NOT be in RESET state! */
3015        if (ioc->last_state == MPI_IOC_STATE_RESET) {
3016                printk(KERN_ERR MYNAM
3017                    ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3018                    ioc->name, ioc->last_state);
3019                return -44;
3020        }
3021
3022        facts = &ioc->facts;
3023
3024        /* Destination (reply area)... */
3025        reply_sz = sizeof(*facts);
3026        memset(facts, 0, reply_sz);
3027
3028        /* Request area (get_facts on the stack right now!) */
3029        req_sz = sizeof(get_facts);
3030        memset(&get_facts, 0, req_sz);
3031
3032        get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3033        /* Assert: All other get_facts fields are zero! */
3034
3035        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3036            "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3037            ioc->name, req_sz, reply_sz));
3038
3039        /* No non-zero fields in the get_facts request are greater than
3040         * 1 byte in size, so we can just fire it off as is.
3041         */
3042        r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3043                        reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3044        if (r != 0)
3045                return r;
3046
3047        /*
3048         * Now byte swap (GRRR) the necessary fields before any further
3049         * inspection of reply contents.
3050         *
3051         * But need to do some sanity checks on MsgLength (byte) field
3052         * to make sure we don't zero IOC's req_sz!
3053         */
3054        /* Did we get a valid reply? */
3055        if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3056                if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3057                        /*
3058                         * If not been here, done that, save off first WhoInit value
3059                         */
3060                        if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3061                                ioc->FirstWhoInit = facts->WhoInit;
3062                }
3063
3064                facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3065                facts->MsgContext = le32_to_cpu(facts->MsgContext);
3066                facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3067                facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3068                facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3069                status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3070                /* CHECKME! IOCStatus, IOCLogInfo */
3071
3072                facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3073                facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3074
3075                /*
3076                 * FC f/w version changed between 1.1 and 1.2
3077                 *      Old: u16{Major(4),Minor(4),SubMinor(8)}
3078                 *      New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3079                 */
3080                if (facts->MsgVersion < MPI_VERSION_01_02) {
3081                        /*
3082                         *      Handle old FC f/w style, convert to new...
3083                         */
3084                        u16      oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3085                        facts->FWVersion.Word =
3086                                        ((oldv<<12) & 0xFF000000) |
3087                                        ((oldv<<8)  & 0x000FFF00);
3088                } else
3089                        facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3090
3091                facts->ProductID = le16_to_cpu(facts->ProductID);
3092
3093                if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3094                    > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3095                        ioc->ir_firmware = 1;
3096
3097                facts->CurrentHostMfaHighAddr =
3098                                le32_to_cpu(facts->CurrentHostMfaHighAddr);
3099                facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3100                facts->CurrentSenseBufferHighAddr =
3101                                le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3102                facts->CurReplyFrameSize =
3103                                le16_to_cpu(facts->CurReplyFrameSize);
3104                facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3105
3106                /*
3107                 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3108                 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3109                 * to 14 in MPI-1.01.0x.
3110                 */
3111                if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3112                    facts->MsgVersion > MPI_VERSION_01_00) {
3113                        facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3114                }
3115
3116                sz = facts->FWImageSize;
3117                if ( sz & 0x01 )
3118                        sz += 1;
3119                if ( sz & 0x02 )
3120                        sz += 2;
3121                facts->FWImageSize = sz;
3122
3123                if (!facts->RequestFrameSize) {
3124                        /*  Something is wrong!  */
3125                        printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3126                                        ioc->name);
3127                        return -55;
3128                }
3129
3130                r = sz = facts->BlockSize;
3131                vv = ((63 / (sz * 4)) + 1) & 0x03;
3132                ioc->NB_for_64_byte_frame = vv;
3133                while ( sz )
3134                {
3135                        shiftFactor++;
3136                        sz = sz >> 1;
3137                }
3138                ioc->NBShiftFactor  = shiftFactor;
3139                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3140                    "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3141                    ioc->name, vv, shiftFactor, r));
3142
3143                if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3144                        /*
3145                         * Set values for this IOC's request & reply frame sizes,
3146                         * and request & reply queue depths...
3147                         */
3148                        ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3149                        ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3150                        ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3151                        ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3152
3153                        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3154                                ioc->name, ioc->reply_sz, ioc->reply_depth));
3155                        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz  =%3d, req_depth  =%4d\n",
3156                                ioc->name, ioc->req_sz, ioc->req_depth));
3157
3158                        /* Get port facts! */
3159                        if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3160                                return r;
3161                }
3162        } else {
3163                printk(MYIOC_s_ERR_FMT
3164                     "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3165                     ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3166                     RequestFrameSize)/sizeof(u32)));
3167                return -66;
3168        }
3169
3170        return 0;
3171}
3172
3173/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3174/**
3175 *      GetPortFacts - Send PortFacts request to MPT adapter.
3176 *      @ioc: Pointer to MPT_ADAPTER structure
3177 *      @portnum: Port number
3178 *      @sleepFlag: Specifies whether the process can sleep
3179 *
3180 *      Returns 0 for success, non-zero for failure.
3181 */
3182static int
3183GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3184{
3185        PortFacts_t              get_pfacts;
3186        PortFactsReply_t        *pfacts;
3187        int                      ii;
3188        int                      req_sz;
3189        int                      reply_sz;
3190        int                      max_id;
3191
3192        /* IOC *must* NOT be in RESET state! */
3193        if (ioc->last_state == MPI_IOC_STATE_RESET) {
3194                printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3195                    ioc->name, ioc->last_state );
3196                return -4;
3197        }
3198
3199        pfacts = &ioc->pfacts[portnum];
3200
3201        /* Destination (reply area)...  */
3202        reply_sz = sizeof(*pfacts);
3203        memset(pfacts, 0, reply_sz);
3204
3205        /* Request area (get_pfacts on the stack right now!) */
3206        req_sz = sizeof(get_pfacts);
3207        memset(&get_pfacts, 0, req_sz);
3208
3209        get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3210        get_pfacts.PortNumber = portnum;
3211        /* Assert: All other get_pfacts fields are zero! */
3212
3213        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3214                        ioc->name, portnum));
3215
3216        /* No non-zero fields in the get_pfacts request are greater than
3217         * 1 byte in size, so we can just fire it off as is.
3218         */
3219        ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3220                                reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3221        if (ii != 0)
3222                return ii;
3223
3224        /* Did we get a valid reply? */
3225
3226        /* Now byte swap the necessary fields in the response. */
3227        pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3228        pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3229        pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3230        pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3231        pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3232        pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3233        pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3234        pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3235        pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3236
3237        max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3238            pfacts->MaxDevices;
3239        ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3240        ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3241
3242        /*
3243         * Place all the devices on channels
3244         *
3245         * (for debuging)
3246         */
3247        if (mpt_channel_mapping) {
3248                ioc->devices_per_bus = 1;
3249                ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3250        }
3251
3252        return 0;
3253}
3254
3255/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3256/**
3257 *      SendIocInit - Send IOCInit request to MPT adapter.
3258 *      @ioc: Pointer to MPT_ADAPTER structure
3259 *      @sleepFlag: Specifies whether the process can sleep
3260 *
3261 *      Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3262 *
3263 *      Returns 0 for success, non-zero for failure.
3264 */
3265static int
3266SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3267{
3268        IOCInit_t                ioc_init;
3269        MPIDefaultReply_t        init_reply;
3270        u32                      state;
3271        int                      r;
3272        int                      count;
3273        int                      cntdn;
3274
3275        memset(&ioc_init, 0, sizeof(ioc_init));
3276        memset(&init_reply, 0, sizeof(init_reply));
3277
3278        ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3279        ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3280
3281        /* If we are in a recovery mode and we uploaded the FW image,
3282         * then this pointer is not NULL. Skip the upload a second time.
3283         * Set this flag if cached_fw set for either IOC.
3284         */
3285        if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3286                ioc->upload_fw = 1;
3287        else
3288                ioc->upload_fw = 0;
3289        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3290                   ioc->name, ioc->upload_fw, ioc->facts.Flags));
3291
3292        ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3293        ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3294
3295        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3296                   ioc->name, ioc->facts.MsgVersion));
3297        if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3298                // set MsgVersion and HeaderVersion host driver was built with
3299                ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3300                ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3301
3302                if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3303                        ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3304                } else if(mpt_host_page_alloc(ioc, &ioc_init))
3305                        return -99;
3306        }
3307        ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);   /* in BYTES */
3308
3309        if (ioc->sg_addr_size == sizeof(u64)) {
3310                /* Save the upper 32-bits of the request
3311                 * (reply) and sense buffers.
3312                 */
3313                ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3314                ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3315        } else {
3316                /* Force 32-bit addressing */
3317                ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3318                ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3319        }
3320
3321        ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3322        ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3323        ioc->facts.MaxDevices = ioc_init.MaxDevices;
3324        ioc->facts.MaxBuses = ioc_init.MaxBuses;
3325
3326        dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3327                        ioc->name, &ioc_init));
3328
3329        r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3330                                sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3331        if (r != 0) {
3332                printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3333                return r;
3334        }
3335
3336        /* No need to byte swap the multibyte fields in the reply
3337         * since we don't even look at its contents.
3338         */
3339
3340        dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3341                        ioc->name, &ioc_init));
3342
3343        if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3344                printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3345                return r;
3346        }
3347
3348        /* YIKES!  SUPER IMPORTANT!!!
3349         *  Poll IocState until _OPERATIONAL while IOC is doing
3350         *  LoopInit and TargetDiscovery!
3351         */
3352        count = 0;
3353        cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;    /* 60 seconds */
3354        state = mpt_GetIocState(ioc, 1);
3355        while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3356                if (sleepFlag == CAN_SLEEP) {
3357                        msleep(1);
3358                } else {
3359                        mdelay(1);
3360                }
3361
3362                if (!cntdn) {
3363                        printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3364                                        ioc->name, (int)((count+5)/HZ));
3365                        return -9;
3366                }
3367
3368                state = mpt_GetIocState(ioc, 1);
3369                count++;
3370        }
3371        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3372                        ioc->name, count));
3373
3374        ioc->aen_event_read_flag=0;
3375        return r;
3376}
3377
3378/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3379/**
3380 *      SendPortEnable - Send PortEnable request to MPT adapter port.
3381 *      @ioc: Pointer to MPT_ADAPTER structure
3382 *      @portnum: Port number to enable
3383 *      @sleepFlag: Specifies whether the process can sleep
3384 *
3385 *      Send PortEnable to bring IOC to OPERATIONAL state.
3386 *
3387 *      Returns 0 for success, non-zero for failure.
3388 */
3389static int
3390SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3391{
3392        PortEnable_t             port_enable;
3393        MPIDefaultReply_t        reply_buf;
3394        int      rc;
3395        int      req_sz;
3396        int      reply_sz;
3397
3398        /*  Destination...  */
3399        reply_sz = sizeof(MPIDefaultReply_t);
3400        memset(&reply_buf, 0, reply_sz);
3401
3402        req_sz = sizeof(PortEnable_t);
3403        memset(&port_enable, 0, req_sz);
3404
3405        port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3406        port_enable.PortNumber = portnum;
3407/*      port_enable.ChainOffset = 0;            */
3408/*      port_enable.MsgFlags = 0;               */
3409/*      port_enable.MsgContext = 0;             */
3410
3411        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3412                        ioc->name, portnum, &port_enable));
3413
3414        /* RAID FW may take a long time to enable
3415         */
3416        if (ioc->ir_firmware || ioc->bus_type == SAS) {
3417                rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3418                (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3419                300 /*seconds*/, sleepFlag);
3420        } else {
3421                rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3422                (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3423                30 /*seconds*/, sleepFlag);
3424        }
3425        return rc;
3426}
3427
3428/**
3429 *      mpt_alloc_fw_memory - allocate firmware memory
3430 *      @ioc: Pointer to MPT_ADAPTER structure
3431 *      @size: total FW bytes
3432 *
3433 *      If memory has already been allocated, the same (cached) value
3434 *      is returned.
3435 *
3436 *      Return 0 if successful, or non-zero for failure
3437 **/
3438int
3439mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3440{
3441        int rc;
3442
3443        if (ioc->cached_fw) {
3444                rc = 0;  /* use already allocated memory */
3445                goto out;
3446        }
3447        else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3448                ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
3449                ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3450                rc = 0;
3451                goto out;
3452        }
3453        ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3454        if (!ioc->cached_fw) {
3455                printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3456                    ioc->name);
3457                rc = -1;
3458        } else {
3459                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3460                    ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3461                ioc->alloc_total += size;
3462                rc = 0;
3463        }
3464 out:
3465        return rc;
3466}
3467
3468/**
3469 *      mpt_free_fw_memory - free firmware memory
3470 *      @ioc: Pointer to MPT_ADAPTER structure
3471 *
3472 *      If alt_img is NULL, delete from ioc structure.
3473 *      Else, delete a secondary image in same format.
3474 **/
3475void
3476mpt_free_fw_memory(MPT_ADAPTER *ioc)
3477{
3478        int sz;
3479
3480        if (!ioc->cached_fw)
3481                return;
3482
3483        sz = ioc->facts.FWImageSize;
3484        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3485                 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3486        pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3487        ioc->alloc_total -= sz;
3488        ioc->cached_fw = NULL;
3489}
3490
3491/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3492/**
3493 *      mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3494 *      @ioc: Pointer to MPT_ADAPTER structure
3495 *      @sleepFlag: Specifies whether the process can sleep
3496 *
3497 *      Returns 0 for success, >0 for handshake failure
3498 *              <0 for fw upload failure.
3499 *
3500 *      Remark: If bound IOC and a successful FWUpload was performed
3501 *      on the bound IOC, the second image is discarded
3502 *      and memory is free'd. Both channels must upload to prevent
3503 *      IOC from running in degraded mode.
3504 */
3505static int
3506mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3507{
3508        u8                       reply[sizeof(FWUploadReply_t)];
3509        FWUpload_t              *prequest;
3510        FWUploadReply_t         *preply;
3511        FWUploadTCSGE_t         *ptcsge;
3512        u32                      flagsLength;
3513        int                      ii, sz, reply_sz;
3514        int                      cmdStatus;
3515        int                     request_size;
3516        /* If the image size is 0, we are done.
3517         */
3518        if ((sz = ioc->facts.FWImageSize) == 0)
3519                return 0;
3520
3521        if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3522                return -ENOMEM;
3523
3524        dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3525            ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3526
3527        prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3528            kzalloc(ioc->req_sz, GFP_KERNEL);
3529        if (!prequest) {
3530                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3531                    "while allocating memory \n", ioc->name));
3532                mpt_free_fw_memory(ioc);
3533                return -ENOMEM;
3534        }
3535
3536        preply = (FWUploadReply_t *)&reply;
3537
3538        reply_sz = sizeof(reply);
3539        memset(preply, 0, reply_sz);
3540
3541        prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3542        prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3543
3544        ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3545        ptcsge->DetailsLength = 12;
3546        ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3547        ptcsge->ImageSize = cpu_to_le32(sz);
3548        ptcsge++;
3549
3550        flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3551        ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3552        request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3553            ioc->SGE_size;
3554        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3555            " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3556            ioc->facts.FWImageSize, request_size));
3557        DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3558
3559        ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3560            reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3561
3562        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3563            "rc=%x \n", ioc->name, ii));
3564
3565        cmdStatus = -EFAULT;
3566        if (ii == 0) {
3567                /* Handshake transfer was complete and successful.
3568                 * Check the Reply Frame.
3569                 */
3570                int status;
3571                status = le16_to_cpu(preply->IOCStatus) &
3572                                MPI_IOCSTATUS_MASK;
3573                if (status == MPI_IOCSTATUS_SUCCESS &&
3574                    ioc->facts.FWImageSize ==
3575                    le32_to_cpu(preply->ActualImageSize))
3576                                cmdStatus = 0;
3577        }
3578        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3579                        ioc->name, cmdStatus));
3580
3581
3582        if (cmdStatus) {
3583                ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3584                    "freeing image \n", ioc->name));
3585                mpt_free_fw_memory(ioc);
3586        }
3587        kfree(prequest);
3588
3589        return cmdStatus;
3590}
3591
3592/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3593/**
3594 *      mpt_downloadboot - DownloadBoot code
3595 *      @ioc: Pointer to MPT_ADAPTER structure
3596 *      @pFwHeader: Pointer to firmware header info
3597 *      @sleepFlag: Specifies whether the process can sleep
3598 *
3599 *      FwDownloadBoot requires Programmed IO access.
3600 *
3601 *      Returns 0 for success
3602 *              -1 FW Image size is 0
3603 *              -2 No valid cached_fw Pointer
3604 *              <0 for fw upload failure.
3605 */
3606static int
3607mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3608{
3609        MpiExtImageHeader_t     *pExtImage;
3610        u32                      fwSize;
3611        u32                      diag0val;
3612        int                      count;
3613        u32                     *ptrFw;
3614        u32                      diagRwData;
3615        u32                      nextImage;
3616        u32                      load_addr;
3617        u32                      ioc_state=0;
3618
3619        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3620                                ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3621
3622        CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3623        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3624        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3625        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3626        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3627        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3628
3629        CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3630
3631        /* wait 1 msec */
3632        if (sleepFlag == CAN_SLEEP) {
3633                msleep(1);
3634        } else {
3635                mdelay (1);
3636        }
3637
3638        diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3639        CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3640
3641        for (count = 0; count < 30; count ++) {
3642                diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3643                if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3644                        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3645                                ioc->name, count));
3646                        break;
3647                }
3648                /* wait .1 sec */
3649                if (sleepFlag == CAN_SLEEP) {
3650                        msleep (100);
3651                } else {
3652                        mdelay (100);
3653                }
3654        }
3655
3656        if ( count == 30 ) {
3657                ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3658                "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3659                ioc->name, diag0val));
3660                return -3;
3661        }
3662
3663        CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3664        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3665        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3666        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3667        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3668        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3669
3670        /* Set the DiagRwEn and Disable ARM bits */
3671        CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3672
3673        fwSize = (pFwHeader->ImageSize + 3)/4;
3674        ptrFw = (u32 *) pFwHeader;
3675
3676        /* Write the LoadStartAddress to the DiagRw Address Register
3677         * using Programmed IO
3678         */
3679        if (ioc->errata_flag_1064)
3680                pci_enable_io_access(ioc->pcidev);
3681
3682        CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3683        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3684                ioc->name, pFwHeader->LoadStartAddress));
3685
3686        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3687                                ioc->name, fwSize*4, ptrFw));
3688        while (fwSize--) {
3689                CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3690        }
3691
3692        nextImage = pFwHeader->NextImageHeaderOffset;
3693        while (nextImage) {
3694                pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3695
3696                load_addr = pExtImage->LoadStartAddress;
3697
3698                fwSize = (pExtImage->ImageSize + 3) >> 2;
3699                ptrFw = (u32 *)pExtImage;
3700
3701                ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3702                                                ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3703                CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3704
3705                while (fwSize--) {
3706                        CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3707                }
3708                nextImage = pExtImage->NextImageHeaderOffset;
3709        }
3710
3711        /* Write the IopResetVectorRegAddr */
3712        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name,  pFwHeader->IopResetRegAddr));
3713        CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3714
3715        /* Write the IopResetVectorValue */
3716        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3717        CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3718
3719        /* Clear the internal flash bad bit - autoincrementing register,
3720         * so must do two writes.
3721         */
3722        if (ioc->bus_type == SPI) {
3723                /*
3724                 * 1030 and 1035 H/W errata, workaround to access
3725                 * the ClearFlashBadSignatureBit
3726                 */
3727                CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3728                diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3729                diagRwData |= 0x40000000;
3730                CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3731                CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3732
3733        } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3734                diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3735                CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3736                    MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3737
3738                /* wait 1 msec */
3739                if (sleepFlag == CAN_SLEEP) {
3740                        msleep (1);
3741                } else {
3742                        mdelay (1);
3743                }
3744        }
3745
3746        if (ioc->errata_flag_1064)
3747                pci_disable_io_access(ioc->pcidev);
3748
3749        diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3750        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3751                "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3752                ioc->name, diag0val));
3753        diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3754        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3755                ioc->name, diag0val));
3756        CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3757
3758        /* Write 0xFF to reset the sequencer */
3759        CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3760
3761        if (ioc->bus_type == SAS) {
3762                ioc_state = mpt_GetIocState(ioc, 0);
3763                if ( (GetIocFacts(ioc, sleepFlag,
3764                                MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3765                        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3766                                        ioc->name, ioc_state));
3767                        return -EFAULT;
3768                }
3769        }
3770
3771        for (count=0; count<HZ*20; count++) {
3772                if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3773                        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3774                                "downloadboot successful! (count=%d) IocState=%x\n",
3775                                ioc->name, count, ioc_state));
3776                        if (ioc->bus_type == SAS) {
3777                                return 0;
3778                        }
3779                        if ((SendIocInit(ioc, sleepFlag)) != 0) {
3780                                ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3781                                        "downloadboot: SendIocInit failed\n",
3782                                        ioc->name));
3783                                return -EFAULT;
3784                        }
3785                        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3786                                        "downloadboot: SendIocInit successful\n",
3787                                        ioc->name));
3788                        return 0;
3789                }
3790                if (sleepFlag == CAN_SLEEP) {
3791                        msleep (10);
3792                } else {
3793                        mdelay (10);
3794                }
3795        }
3796        ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3797                "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3798        return -EFAULT;
3799}
3800
3801/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3802/**
3803 *      KickStart - Perform hard reset of MPT adapter.
3804 *      @ioc: Pointer to MPT_ADAPTER structure
3805 *      @force: Force hard reset
3806 *      @sleepFlag: Specifies whether the process can sleep
3807 *
3808 *      This routine places MPT adapter in diagnostic mode via the
3809 *      WriteSequence register, and then performs a hard reset of adapter
3810 *      via the Diagnostic register.
3811 *
3812 *      Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
3813 *                      or NO_SLEEP (interrupt thread, use mdelay)
3814 *                force - 1 if doorbell active, board fault state
3815 *                              board operational, IOC_RECOVERY or
3816 *                              IOC_BRINGUP and there is an alt_ioc.
3817 *                        0 else
3818 *
3819 *      Returns:
3820 *               1 - hard reset, READY
3821 *               0 - no reset due to History bit, READY
3822 *              -1 - no reset due to History bit but not READY
3823 *                   OR reset but failed to come READY
3824 *              -2 - no reset, could not enter DIAG mode
3825 *              -3 - reset but bad FW bit
3826 */
3827static int
3828KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3829{
3830        int hard_reset_done = 0;
3831        u32 ioc_state=0;
3832        int cnt,cntdn;
3833
3834        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3835        if (ioc->bus_type == SPI) {
3836                /* Always issue a Msg Unit Reset first. This will clear some
3837                 * SCSI bus hang conditions.
3838                 */
3839                SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3840
3841                if (sleepFlag == CAN_SLEEP) {
3842                        msleep (1000);
3843                } else {
3844                        mdelay (1000);
3845                }
3846        }
3847
3848        hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3849        if (hard_reset_done < 0)
3850                return hard_reset_done;
3851
3852        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3853                ioc->name));
3854
3855        cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;     /* 2 seconds */
3856        for (cnt=0; cnt<cntdn; cnt++) {
3857                ioc_state = mpt_GetIocState(ioc, 1);
3858                if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3859                        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3860                                        ioc->name, cnt));
3861                        return hard_reset_done;
3862                }
3863                if (sleepFlag == CAN_SLEEP) {
3864                        msleep (10);
3865                } else {
3866                        mdelay (10);
3867                }
3868        }
3869
3870        dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3871                ioc->name, mpt_GetIocState(ioc, 0)));
3872        return -1;
3873}
3874
3875/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3876/**
3877 *      mpt_diag_reset - Perform hard reset of the adapter.
3878 *      @ioc: Pointer to MPT_ADAPTER structure
3879 *      @ignore: Set if to honor and clear to ignore
3880 *              the reset history bit
3881 *      @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3882 *              else set to NO_SLEEP (use mdelay instead)
3883 *
3884 *      This routine places the adapter in diagnostic mode via the
3885 *      WriteSequence register and then performs a hard reset of adapter
3886 *      via the Diagnostic register. Adapter should be in ready state
3887 *      upon successful completion.
3888 *
3889 *      Returns:  1  hard reset successful
3890 *                0  no reset performed because reset history bit set
3891 *               -2  enabling diagnostic mode failed
3892 *               -3  diagnostic reset failed
3893 */
3894static int
3895mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3896{
3897        u32 diag0val;
3898        u32 doorbell;
3899        int hard_reset_done = 0;
3900        int count = 0;
3901        u32 diag1val = 0;
3902        MpiFwHeader_t *cached_fw;       /* Pointer to FW */
3903        u8       cb_idx;
3904
3905        /* Clear any existing interrupts */
3906        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3907
3908        if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3909
3910                if (!ignore)
3911                        return 0;
3912
3913                drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3914                        "address=%p\n",  ioc->name, __func__,
3915                        &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3916                CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3917                if (sleepFlag == CAN_SLEEP)
3918                        msleep(1);
3919                else
3920                        mdelay(1);
3921
3922                /*
3923                 * Call each currently registered protocol IOC reset handler
3924                 * with pre-reset indication.
3925                 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3926                 * MptResetHandlers[] registered yet.
3927                 */
3928                for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3929                        if (MptResetHandlers[cb_idx])
3930                                (*(MptResetHandlers[cb_idx]))(ioc,
3931                                                MPT_IOC_PRE_RESET);
3932                }
3933
3934                for (count = 0; count < 60; count ++) {
3935                        doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3936                        doorbell &= MPI_IOC_STATE_MASK;
3937
3938                        drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3939                                "looking for READY STATE: doorbell=%x"
3940                                " count=%d\n",
3941                                ioc->name, doorbell, count));
3942
3943                        if (doorbell == MPI_IOC_STATE_READY) {
3944                                return 1;
3945                        }
3946
3947                        /* wait 1 sec */
3948                        if (sleepFlag == CAN_SLEEP)
3949                                msleep(1000);
3950                        else
3951                                mdelay(1000);
3952                }
3953                return -1;
3954        }
3955
3956        /* Use "Diagnostic reset" method! (only thing available!) */
3957        diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3958
3959        if (ioc->debug_level & MPT_DEBUG) {
3960                if (ioc->alt_ioc)
3961                        diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3962                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3963                        ioc->name, diag0val, diag1val));
3964        }
3965
3966        /* Do the reset if we are told to ignore the reset history
3967         * or if the reset history is 0
3968         */
3969        if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3970                while ((diag0val & MPI_DIAG_DRWE) == 0) {
3971                        /* Write magic sequence to WriteSequence register
3972                         * Loop until in diagnostic mode
3973                         */
3974                        CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3975                        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3976                        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3977                        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3978                        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3979                        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3980
3981                        /* wait 100 msec */
3982                        if (sleepFlag == CAN_SLEEP) {
3983                                msleep (100);
3984                        } else {
3985                                mdelay (100);
3986                        }
3987
3988                        count++;
3989                        if (count > 20) {
3990                                printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3991                                                ioc->name, diag0val);
3992                                return -2;
3993
3994                        }
3995
3996                        diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3997
3998                        dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3999                                        ioc->name, diag0val));
4000                }
4001
4002                if (ioc->debug_level & MPT_DEBUG) {
4003                        if (ioc->alt_ioc)
4004                                diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4005                        dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4006                                ioc->name, diag0val, diag1val));
4007                }
4008                /*
4009                 * Disable the ARM (Bug fix)
4010                 *
4011                 */
4012                CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4013                mdelay(1);
4014
4015                /*
4016                 * Now hit the reset bit in the Diagnostic register
4017                 * (THE BIG HAMMER!) (Clears DRWE bit).
4018                 */
4019                CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4020                hard_reset_done = 1;
4021                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4022                                ioc->name));
4023
4024                /*
4025                 * Call each currently registered protocol IOC reset handler
4026                 * with pre-reset indication.
4027                 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4028                 * MptResetHandlers[] registered yet.
4029                 */
4030                for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4031                        if (MptResetHandlers[cb_idx]) {
4032                                mpt_signal_reset(cb_idx,
4033                                        ioc, MPT_IOC_PRE_RESET);
4034                                if (ioc->alt_ioc) {
4035                                        mpt_signal_reset(cb_idx,
4036                                        ioc->alt_ioc, MPT_IOC_PRE_RESET);
4037                                }
4038                        }
4039                }
4040
4041                if (ioc->cached_fw)
4042                        cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4043                else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4044                        cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4045                else
4046                        cached_fw = NULL;
4047                if (cached_fw) {
4048                        /* If the DownloadBoot operation fails, the
4049                         * IOC will be left unusable. This is a fatal error
4050                         * case.  _diag_reset will return < 0
4051                         */
4052                        for (count = 0; count < 30; count ++) {
4053                                diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4054                                if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4055                                        break;
4056                                }
4057
4058                                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4059                                        ioc->name, diag0val, count));
4060                                /* wait 1 sec */
4061                                if (sleepFlag == CAN_SLEEP) {
4062                                        msleep (1000);
4063                                } else {
4064                                        mdelay (1000);
4065                                }
4066                        }
4067                        if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4068                                printk(MYIOC_s_WARN_FMT
4069                                        "firmware downloadboot failure (%d)!\n", ioc->name, count);
4070                        }
4071
4072                } else {
4073                        /* Wait for FW to reload and for board
4074                         * to go to the READY state.
4075                         * Maximum wait is 60 seconds.
4076                         * If fail, no error will check again
4077                         * with calling program.
4078                         */
4079                        for (count = 0; count < 60; count ++) {
4080                                doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4081                                doorbell &= MPI_IOC_STATE_MASK;
4082
4083                                drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4084                                    "looking for READY STATE: doorbell=%x"
4085                                    " count=%d\n", ioc->name, doorbell, count));
4086
4087                                if (doorbell == MPI_IOC_STATE_READY) {
4088                                        break;
4089                                }
4090
4091                                /* wait 1 sec */
4092                                if (sleepFlag == CAN_SLEEP) {
4093                                        msleep (1000);
4094                                } else {
4095                                        mdelay (1000);
4096                                }
4097                        }
4098
4099                        if (doorbell != MPI_IOC_STATE_READY)
4100                                printk(MYIOC_s_ERR_FMT "Failed to come READY "
4101                                    "after reset! IocState=%x", ioc->name,
4102                                    doorbell);
4103                }
4104        }
4105
4106        diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4107        if (ioc->debug_level & MPT_DEBUG) {
4108                if (ioc->alt_ioc)
4109                        diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4110                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4111                        ioc->name, diag0val, diag1val));
4112        }
4113
4114        /* Clear RESET_HISTORY bit!  Place board in the
4115         * diagnostic mode to update the diag register.
4116         */
4117        diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4118        count = 0;
4119        while ((diag0val & MPI_DIAG_DRWE) == 0) {
4120                /* Write magic sequence to WriteSequence register
4121                 * Loop until in diagnostic mode
4122                 */
4123                CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4124                CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4125                CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4126                CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4127                CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4128                CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4129
4130                /* wait 100 msec */
4131                if (sleepFlag == CAN_SLEEP) {
4132                        msleep (100);
4133                } else {
4134                        mdelay (100);
4135                }
4136
4137                count++;
4138                if (count > 20) {
4139                        printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4140                                        ioc->name, diag0val);
4141                        break;
4142                }
4143                diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4144        }
4145        diag0val &= ~MPI_DIAG_RESET_HISTORY;
4146        CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4147        diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4148        if (diag0val & MPI_DIAG_RESET_HISTORY) {
4149                printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4150                                ioc->name);
4151        }
4152
4153        /* Disable Diagnostic Mode
4154         */
4155        CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4156
4157        /* Check FW reload status flags.
4158         */
4159        diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4160        if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4161                printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4162                                ioc->name, diag0val);
4163                return -3;
4164        }
4165
4166        if (ioc->debug_level & MPT_DEBUG) {
4167                if (ioc->alt_ioc)
4168                        diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4169                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4170                        ioc->name, diag0val, diag1val));
4171        }
4172
4173        /*
4174         * Reset flag that says we've enabled event notification
4175         */
4176        ioc->facts.EventState = 0;
4177
4178        if (ioc->alt_ioc)
4179                ioc->alt_ioc->facts.EventState = 0;
4180
4181        return hard_reset_done;
4182}
4183
4184/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4185/**
4186 *      SendIocReset - Send IOCReset request to MPT adapter.
4187 *      @ioc: Pointer to MPT_ADAPTER structure
4188 *      @reset_type: reset type, expected values are
4189 *      %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4190 *      @sleepFlag: Specifies whether the process can sleep
4191 *
4192 *      Send IOCReset request to the MPT adapter.
4193 *
4194 *      Returns 0 for success, non-zero for failure.
4195 */
4196static int
4197SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4198{
4199        int r;
4200        u32 state;
4201        int cntdn, count;
4202
4203        drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4204                        ioc->name, reset_type));
4205        CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4206        if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4207                return r;
4208
4209        /* FW ACK'd request, wait for READY state
4210         */
4211        count = 0;
4212        cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;    /* 15 seconds */
4213
4214        while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4215                cntdn--;
4216                count++;
4217                if (!cntdn) {
4218                        if (sleepFlag != CAN_SLEEP)
4219                                count *= 10;
4220
4221                        printk(MYIOC_s_ERR_FMT
4222                            "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4223                            ioc->name, state, (int)((count+5)/HZ));
4224                        return -ETIME;
4225                }
4226
4227                if (sleepFlag == CAN_SLEEP) {
4228                        msleep(1);
4229                } else {
4230                        mdelay (1);     /* 1 msec delay */
4231                }
4232        }
4233
4234        /* TODO!
4235         *  Cleanup all event stuff for this IOC; re-issue EventNotification
4236         *  request if needed.
4237         */
4238        if (ioc->facts.Function)
4239                ioc->facts.EventState = 0;
4240
4241        return 0;
4242}
4243
4244/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4245/**
4246 *      initChainBuffers - Allocate memory for and initialize chain buffers
4247 *      @ioc: Pointer to MPT_ADAPTER structure
4248 *
4249 *      Allocates memory for and initializes chain buffers,
4250 *      chain buffer control arrays and spinlock.
4251 */
4252static int
4253initChainBuffers(MPT_ADAPTER *ioc)
4254{
4255        u8              *mem;
4256        int             sz, ii, num_chain;
4257        int             scale, num_sge, numSGE;
4258
4259        /* ReqToChain size must equal the req_depth
4260         * index = req_idx
4261         */
4262        if (ioc->ReqToChain == NULL) {
4263                sz = ioc->req_depth * sizeof(int);
4264                mem = kmalloc(sz, GFP_ATOMIC);
4265                if (mem == NULL)
4266                        return -1;
4267
4268                ioc->ReqToChain = (int *) mem;
4269                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc  @ %p, sz=%d bytes\n",
4270                                ioc->name, mem, sz));
4271                mem = kmalloc(sz, GFP_ATOMIC);
4272                if (mem == NULL)
4273                        return -1;
4274
4275                ioc->RequestNB = (int *) mem;
4276                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc  @ %p, sz=%d bytes\n",
4277                                ioc->name, mem, sz));
4278        }
4279        for (ii = 0; ii < ioc->req_depth; ii++) {
4280                ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4281        }
4282
4283        /* ChainToChain size must equal the total number
4284         * of chain buffers to be allocated.
4285         * index = chain_idx
4286         *
4287         * Calculate the number of chain buffers needed(plus 1) per I/O
4288         * then multiply the maximum number of simultaneous cmds
4289         *
4290         * num_sge = num sge in request frame + last chain buffer
4291         * scale = num sge per chain buffer if no chain element
4292         */
4293        scale = ioc->req_sz / ioc->SGE_size;
4294        if (ioc->sg_addr_size == sizeof(u64))
4295                num_sge =  scale + (ioc->req_sz - 60) / ioc->SGE_size;
4296        else
4297                num_sge =  1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4298
4299        if (ioc->sg_addr_size == sizeof(u64)) {
4300                numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4301                        (ioc->req_sz - 60) / ioc->SGE_size;
4302        } else {
4303                numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4304                    scale + (ioc->req_sz - 64) / ioc->SGE_size;
4305        }
4306        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4307                ioc->name, num_sge, numSGE));
4308
4309        if (ioc->bus_type == FC) {
4310                if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4311                        numSGE = MPT_SCSI_FC_SG_DEPTH;
4312        } else {
4313                if (numSGE > MPT_SCSI_SG_DEPTH)
4314                        numSGE = MPT_SCSI_SG_DEPTH;
4315        }
4316
4317        num_chain = 1;
4318        while (numSGE - num_sge > 0) {
4319                num_chain++;
4320                num_sge += (scale - 1);
4321        }
4322        num_chain++;
4323
4324        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4325                ioc->name, numSGE, num_sge, num_chain));
4326
4327        if (ioc->bus_type == SPI)
4328                num_chain *= MPT_SCSI_CAN_QUEUE;
4329        else if (ioc->bus_type == SAS)
4330                num_chain *= MPT_SAS_CAN_QUEUE;
4331        else
4332                num_chain *= MPT_FC_CAN_QUEUE;
4333
4334        ioc->num_chain = num_chain;
4335
4336        sz = num_chain * sizeof(int);
4337        if (ioc->ChainToChain == NULL) {
4338                mem = kmalloc(sz, GFP_ATOMIC);
4339                if (mem == NULL)
4340                        return -1;
4341
4342                ioc->ChainToChain = (int *) mem;
4343                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4344                                ioc->name, mem, sz));
4345        } else {
4346                mem = (u8 *) ioc->ChainToChain;
4347        }
4348        memset(mem, 0xFF, sz);
4349        return num_chain;
4350}
4351
4352/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4353/**
4354 *      PrimeIocFifos - Initialize IOC request and reply FIFOs.
4355 *      @ioc: Pointer to MPT_ADAPTER structure
4356 *
4357 *      This routine allocates memory for the MPT reply and request frame
4358 *      pools (if necessary), and primes the IOC reply FIFO with
4359 *      reply frames.
4360 *
4361 *      Returns 0 for success, non-zero for failure.
4362 */
4363static int
4364PrimeIocFifos(MPT_ADAPTER *ioc)
4365{
4366        MPT_FRAME_HDR *mf;
4367        unsigned long flags;
4368        dma_addr_t alloc_dma;
4369        u8 *mem;
4370        int i, reply_sz, sz, total_size, num_chain;
4371        u64     dma_mask;
4372
4373        dma_mask = 0;
4374
4375        /*  Prime reply FIFO...  */
4376
4377        if (ioc->reply_frames == NULL) {
4378                if ( (num_chain = initChainBuffers(ioc)) < 0)
4379                        return -1;
4380                /*
4381                 * 1078 errata workaround for the 36GB limitation
4382                 */
4383                if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4384                    ioc->dma_mask > DMA_BIT_MASK(35)) {
4385                        if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4386                            && !pci_set_consistent_dma_mask(ioc->pcidev,
4387                            DMA_BIT_MASK(32))) {
4388                                dma_mask = DMA_BIT_MASK(35);
4389                                d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4390                                    "setting 35 bit addressing for "
4391                                    "Request/Reply/Chain and Sense Buffers\n",
4392                                    ioc->name));
4393                        } else {
4394                                /*Reseting DMA mask to 64 bit*/
4395                                pci_set_dma_mask(ioc->pcidev,
4396                                        DMA_BIT_MASK(64));
4397                                pci_set_consistent_dma_mask(ioc->pcidev,
4398                                        DMA_BIT_MASK(64));
4399
4400                                printk(MYIOC_s_ERR_FMT
4401                                    "failed setting 35 bit addressing for "
4402                                    "Request/Reply/Chain and Sense Buffers\n",
4403                                    ioc->name);
4404                                return -1;
4405                        }
4406                }
4407
4408                total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4409                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4410                                ioc->name, ioc->reply_sz, ioc->reply_depth));
4411                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4412                                ioc->name, reply_sz, reply_sz));
4413
4414                sz = (ioc->req_sz * ioc->req_depth);
4415                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4416                                ioc->name, ioc->req_sz, ioc->req_depth));
4417                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4418                                ioc->name, sz, sz));
4419                total_size += sz;
4420
4421                sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4422                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4423                                ioc->name, ioc->req_sz, num_chain));
4424                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4425                                ioc->name, sz, sz, num_chain));
4426
4427                total_size += sz;
4428                mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4429                if (mem == NULL) {
4430                        printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4431                                ioc->name);
4432                        goto out_fail;
4433                }
4434
4435                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4436                                ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4437
4438                memset(mem, 0, total_size);
4439                ioc->alloc_total += total_size;
4440                ioc->alloc = mem;
4441                ioc->alloc_dma = alloc_dma;
4442                ioc->alloc_sz = total_size;
4443                ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4444                ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4445
4446                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4447                        ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4448
4449                alloc_dma += reply_sz;
4450                mem += reply_sz;
4451
4452                /*  Request FIFO - WE manage this!  */
4453
4454                ioc->req_frames = (MPT_FRAME_HDR *) mem;
4455                ioc->req_frames_dma = alloc_dma;
4456
4457                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4458                                ioc->name, mem, (void *)(ulong)alloc_dma));
4459
4460                ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4461
4462#if defined(CONFIG_MTRR) && 0
4463                /*
4464                 *  Enable Write Combining MTRR for IOC's memory region.
4465                 *  (at least as much as we can; "size and base must be
4466                 *  multiples of 4 kiB"
4467                 */
4468                ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4469                                         sz,
4470                                         MTRR_TYPE_WRCOMB, 1);
4471                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4472                                ioc->name, ioc->req_frames_dma, sz));
4473#endif
4474
4475                for (i = 0; i < ioc->req_depth; i++) {
4476                        alloc_dma += ioc->req_sz;
4477                        mem += ioc->req_sz;
4478                }
4479
4480                ioc->ChainBuffer = mem;
4481                ioc->ChainBufferDMA = alloc_dma;
4482
4483                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4484                        ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4485
4486                /* Initialize the free chain Q.
4487                */
4488
4489                INIT_LIST_HEAD(&ioc->FreeChainQ);
4490
4491                /* Post the chain buffers to the FreeChainQ.
4492                */
4493                mem = (u8 *)ioc->ChainBuffer;
4494                for (i=0; i < num_chain; i++) {
4495                        mf = (MPT_FRAME_HDR *) mem;
4496                        list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4497                        mem += ioc->req_sz;
4498                }
4499
4500                /* Initialize Request frames linked list
4501                 */
4502                alloc_dma = ioc->req_frames_dma;
4503                mem = (u8 *) ioc->req_frames;
4504
4505                spin_lock_irqsave(&ioc->FreeQlock, flags);
4506                INIT_LIST_HEAD(&ioc->FreeQ);
4507                for (i = 0; i < ioc->req_depth; i++) {
4508                        mf = (MPT_FRAME_HDR *) mem;
4509
4510                        /*  Queue REQUESTs *internally*!  */
4511                        list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4512
4513                        mem += ioc->req_sz;
4514                }
4515                spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4516
4517                sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4518                ioc->sense_buf_pool =
4519                        pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4520                if (ioc->sense_buf_pool == NULL) {
4521                        printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4522                                ioc->name);
4523                        goto out_fail;
4524                }
4525
4526                ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4527                ioc->alloc_total += sz;
4528                dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4529                        ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4530
4531        }
4532
4533        /* Post Reply frames to FIFO
4534         */
4535        alloc_dma = ioc->alloc_dma;
4536        dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4537                ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4538
4539        for (i = 0; i < ioc->reply_depth; i++) {
4540                /*  Write each address to the IOC!  */
4541                CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4542                alloc_dma += ioc->reply_sz;
4543        }
4544
4545        if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4546            ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4547            ioc->dma_mask))
4548                d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4549                    "restoring 64 bit addressing\n", ioc->name));
4550
4551        return 0;
4552
4553out_fail:
4554
4555        if (ioc->alloc != NULL) {
4556                sz = ioc->alloc_sz;
4557                pci_free_consistent(ioc->pcidev,
4558                                sz,
4559                                ioc->alloc, ioc->alloc_dma);
4560                ioc->reply_frames = NULL;
4561                ioc->req_frames = NULL;
4562                ioc->alloc_total -= sz;
4563        }
4564        if (ioc->sense_buf_pool != NULL) {
4565                sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4566                pci_free_consistent(ioc->pcidev,
4567                                sz,
4568                                ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4569                ioc->sense_buf_pool = NULL;
4570        }
4571
4572        if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4573            DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4574            DMA_BIT_MASK(64)))
4575                d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4576                    "restoring 64 bit addressing\n", ioc->name));
4577
4578        return -1;
4579}
4580
4581/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4582/**
4583 *      mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4584 *      from IOC via doorbell handshake method.
4585 *      @ioc: Pointer to MPT_ADAPTER structure
4586 *      @reqBytes: Size of the request in bytes
4587 *      @req: Pointer to MPT request frame
4588 *      @replyBytes: Expected size of the reply in bytes
4589 *      @u16reply: Pointer to area where reply should be written
4590 *      @maxwait: Max wait time for a reply (in seconds)
4591 *      @sleepFlag: Specifies whether the process can sleep
4592 *
4593 *      NOTES: It is the callers responsibility to byte-swap fields in the
4594 *      request which are greater than 1 byte in size.  It is also the
4595 *      callers responsibility to byte-swap response fields which are
4596 *      greater than 1 byte in size.
4597 *
4598 *      Returns 0 for success, non-zero for failure.
4599 */
4600static int
4601mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4602                int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4603{
4604        MPIDefaultReply_t *mptReply;
4605        int failcnt = 0;
4606        int t;
4607
4608        /*
4609         * Get ready to cache a handshake reply
4610         */
4611        ioc->hs_reply_idx = 0;
4612        mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4613        mptReply->MsgLength = 0;
4614
4615        /*
4616         * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4617         * then tell IOC that we want to handshake a request of N words.
4618         * (WRITE u32val to Doorbell reg).
4619         */
4620        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4621        CHIPREG_WRITE32(&ioc->chip->Doorbell,
4622                        ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4623                         ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4624
4625        /*
4626         * Wait for IOC's doorbell handshake int
4627         */
4628        if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4629                failcnt++;
4630
4631        dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4632                        ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4633
4634        /* Read doorbell and check for active bit */
4635        if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4636                        return -1;
4637
4638        /*
4639         * Clear doorbell int (WRITE 0 to IntStatus reg),
4640         * then wait for IOC to ACKnowledge that it's ready for
4641         * our handshake request.
4642         */
4643        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4644        if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4645                failcnt++;
4646
4647        if (!failcnt) {
4648                int      ii;
4649                u8      *req_as_bytes = (u8 *) req;
4650
4651                /*
4652                 * Stuff request words via doorbell handshake,
4653                 * with ACK from IOC for each.
4654                 */
4655                for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4656                        u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
4657                                    (req_as_bytes[(ii*4) + 1] <<  8) |
4658                                    (req_as_bytes[(ii*4) + 2] << 16) |
4659                                    (req_as_bytes[(ii*4) + 3] << 24));
4660
4661                        CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4662                        if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4663                                failcnt++;
4664                }
4665
4666                dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4667                DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4668
4669                dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4670                                ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4671
4672                /*
4673                 * Wait for completion of doorbell handshake reply from the IOC
4674                 */
4675                if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4676                        failcnt++;
4677
4678                dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4679                                ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4680
4681                /*
4682                 * Copy out the cached reply...
4683                 */
4684                for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4685                        u16reply[ii] = ioc->hs_reply[ii];
4686        } else {
4687                return -99;
4688        }
4689
4690        return -failcnt;
4691}
4692
4693/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4694/**
4695 *      WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4696 *      @ioc: Pointer to MPT_ADAPTER structure
4697 *      @howlong: How long to wait (in seconds)
4698 *      @sleepFlag: Specifies whether the process can sleep
4699 *
4700 *      This routine waits (up to ~2 seconds max) for IOC doorbell
4701 *      handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4702 *      bit in its IntStatus register being clear.
4703 *
4704 *      Returns a negative value on failure, else wait loop count.
4705 */
4706static int
4707WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4708{
4709        int cntdn;
4710        int count = 0;
4711        u32 intstat=0;
4712
4713        cntdn = 1000 * howlong;
4714
4715        if (sleepFlag == CAN_SLEEP) {
4716                while (--cntdn) {
4717                        msleep (1);
4718                        intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4719                        if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4720                                break;
4721                        count++;
4722                }
4723        } else {
4724                while (--cntdn) {
4725                        udelay (1000);
4726                        intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4727                        if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4728                                break;
4729                        count++;
4730                }
4731        }
4732
4733        if (cntdn) {
4734                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4735                                ioc->name, count));
4736                return count;
4737        }
4738
4739        printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4740                        ioc->name, count, intstat);
4741        return -1;
4742}
4743
4744/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4745/**
4746 *      WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4747 *      @ioc: Pointer to MPT_ADAPTER structure
4748 *      @howlong: How long to wait (in seconds)
4749 *      @sleepFlag: Specifies whether the process can sleep
4750 *
4751 *      This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4752 *      (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4753 *
4754 *      Returns a negative value on failure, else wait loop count.
4755 */
4756static int
4757WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4758{
4759        int cntdn;
4760        int count = 0;
4761        u32 intstat=0;
4762
4763        cntdn = 1000 * howlong;
4764        if (sleepFlag == CAN_SLEEP) {
4765                while (--cntdn) {
4766                        intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4767                        if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4768                                break;
4769                        msleep(1);
4770                        count++;
4771                }
4772        } else {
4773                while (--cntdn) {
4774                        intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4775                        if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4776                                break;
4777                        udelay (1000);
4778                        count++;
4779                }
4780        }
4781
4782        if (cntdn) {
4783                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4784                                ioc->name, count, howlong));
4785                return count;
4786        }
4787
4788        printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4789                        ioc->name, count, intstat);
4790        return -1;
4791}
4792
4793/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4794/**
4795 *      WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4796 *      @ioc: Pointer to MPT_ADAPTER structure
4797 *      @howlong: How long to wait (in seconds)
4798 *      @sleepFlag: Specifies whether the process can sleep
4799 *
4800 *      This routine polls the IOC for a handshake reply, 16 bits at a time.
4801 *      Reply is cached to IOC private area large enough to hold a maximum
4802 *      of 128 bytes of reply data.
4803 *
4804 *      Returns a negative value on failure, else size of reply in WORDS.
4805 */
4806static int
4807WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4808{
4809        int u16cnt = 0;
4810        int failcnt = 0;
4811        int t;
4812        u16 *hs_reply = ioc->hs_reply;
4813        volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4814        u16 hword;
4815
4816        hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4817
4818        /*
4819         * Get first two u16's so we can look at IOC's intended reply MsgLength
4820         */
4821        u16cnt=0;
4822        if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4823                failcnt++;
4824        } else {
4825                hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4826                CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4827                if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4828                        failcnt++;
4829                else {
4830                        hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4831                        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4832                }
4833        }
4834
4835        dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4836                        ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4837                        failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4838
4839        /*
4840         * If no error (and IOC said MsgLength is > 0), piece together
4841         * reply 16 bits at a time.
4842         */
4843        for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4844                if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4845                        failcnt++;
4846                hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4847                /* don't overflow our IOC hs_reply[] buffer! */
4848                if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4849                        hs_reply[u16cnt] = hword;
4850                CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4851        }
4852
4853        if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4854                failcnt++;
4855        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4856
4857        if (failcnt) {
4858                printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4859                                ioc->name);
4860                return -failcnt;
4861        }
4862#if 0
4863        else if (u16cnt != (2 * mptReply->MsgLength)) {
4864                return -101;
4865        }
4866        else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4867                return -102;
4868        }
4869#endif
4870
4871        dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4872        DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4873
4874        dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4875                        ioc->name, t, u16cnt/2));
4876        return u16cnt/2;
4877}
4878
4879/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4880/**
4881 *      GetLanConfigPages - Fetch LANConfig pages.
4882 *      @ioc: Pointer to MPT_ADAPTER structure
4883 *
4884 *      Return: 0 for success
4885 *      -ENOMEM if no memory available
4886 *              -EPERM if not allowed due to ISR context
4887 *              -EAGAIN if no msg frames currently available
4888 *              -EFAULT for non-successful reply or no reply (timeout)
4889 */
4890static int
4891GetLanConfigPages(MPT_ADAPTER *ioc)
4892{
4893        ConfigPageHeader_t       hdr;
4894        CONFIGPARMS              cfg;
4895        LANPage0_t              *ppage0_alloc;
4896        dma_addr_t               page0_dma;
4897        LANPage1_t              *ppage1_alloc;
4898        dma_addr_t               page1_dma;
4899        int                      rc = 0;
4900        int                      data_sz;
4901        int                      copy_sz;
4902
4903        /* Get LAN Page 0 header */
4904        hdr.PageVersion = 0;
4905        hdr.PageLength = 0;
4906        hdr.PageNumber = 0;
4907        hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4908        cfg.cfghdr.hdr = &hdr;
4909        cfg.physAddr = -1;
4910        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4911        cfg.dir = 0;
4912        cfg.pageAddr = 0;
4913        cfg.timeout = 0;
4914
4915        if ((rc = mpt_config(ioc, &cfg)) != 0)
4916                return rc;
4917
4918        if (hdr.PageLength > 0) {
4919                data_sz = hdr.PageLength * 4;
4920                ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4921                rc = -ENOMEM;
4922                if (ppage0_alloc) {
4923                        memset((u8 *)ppage0_alloc, 0, data_sz);
4924                        cfg.physAddr = page0_dma;
4925                        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4926
4927                        if ((rc = mpt_config(ioc, &cfg)) == 0) {
4928                                /* save the data */
4929                                copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4930                                memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4931
4932                        }
4933
4934                        pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4935
4936                        /* FIXME!
4937                         *      Normalize endianness of structure data,
4938                         *      by byte-swapping all > 1 byte fields!
4939                         */
4940
4941                }
4942
4943                if (rc)
4944                        return rc;
4945        }
4946
4947        /* Get LAN Page 1 header */
4948        hdr.PageVersion = 0;
4949        hdr.PageLength = 0;
4950        hdr.PageNumber = 1;
4951        hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4952        cfg.cfghdr.hdr = &hdr;
4953        cfg.physAddr = -1;
4954        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4955        cfg.dir = 0;
4956        cfg.pageAddr = 0;
4957
4958        if ((rc = mpt_config(ioc, &cfg)) != 0)
4959                return rc;
4960
4961        if (hdr.PageLength == 0)
4962                return 0;
4963
4964        data_sz = hdr.PageLength * 4;
4965        rc = -ENOMEM;
4966        ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4967        if (ppage1_alloc) {
4968                memset((u8 *)ppage1_alloc, 0, data_sz);
4969                cfg.physAddr = page1_dma;
4970                cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4971
4972                if ((rc = mpt_config(ioc, &cfg)) == 0) {
4973                        /* save the data */
4974                        copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4975                        memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4976                }
4977
4978                pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4979
4980                /* FIXME!
4981                 *      Normalize endianness of structure data,
4982                 *      by byte-swapping all > 1 byte fields!
4983                 */
4984
4985        }
4986
4987        return rc;
4988}
4989
4990/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4991/**
4992 *      mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4993 *      @ioc: Pointer to MPT_ADAPTER structure
4994 *      @persist_opcode: see below
4995 *
4996 *      MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4997 *              devices not currently present.
4998 *      MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4999 *
5000 *      NOTE: Don't use not this function during interrupt time.
5001 *
5002 *      Returns 0 for success, non-zero error
5003 */
5004
5005/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5006int
5007mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5008{
5009        SasIoUnitControlRequest_t       *sasIoUnitCntrReq;
5010        SasIoUnitControlReply_t         *sasIoUnitCntrReply;
5011        MPT_FRAME_HDR                   *mf = NULL;
5012        MPIHeader_t                     *mpi_hdr;
5013        int                             ret = 0;
5014        unsigned long                   timeleft;
5015
5016        mutex_lock(&ioc->mptbase_cmds.mutex);
5017
5018        /* init the internal cmd struct */
5019        memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5020        INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5021
5022        /* insure garbage is not sent to fw */
5023        switch(persist_opcode) {
5024
5025        case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5026        case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5027                break;
5028
5029        default:
5030                ret = -1;
5031                goto out;
5032        }
5033
5034        printk(KERN_DEBUG  "%s: persist_opcode=%x\n",
5035                __func__, persist_opcode);
5036
5037        /* Get a MF for this command.
5038         */
5039        if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5040                printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5041                ret = -1;
5042                goto out;
5043        }
5044
5045        mpi_hdr = (MPIHeader_t *) mf;
5046        sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5047        memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5048        sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5049        sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5050        sasIoUnitCntrReq->Operation = persist_opcode;
5051
5052        mpt_put_msg_frame(mpt_base_index, ioc, mf);
5053        timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5054        if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5055                ret = -ETIME;
5056                printk(KERN_DEBUG "%s: failed\n", __func__);
5057                if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5058                        goto out;
5059                if (!timeleft) {
5060                        printk(MYIOC_s_WARN_FMT
5061                               "Issuing Reset from %s!!, doorbell=0x%08x\n",
5062                               ioc->name, __func__, mpt_GetIocState(ioc, 0));
5063                        mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5064                        mpt_free_msg_frame(ioc, mf);
5065                }
5066                goto out;
5067        }
5068
5069        if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5070                ret = -1;
5071                goto out;
5072        }
5073
5074        sasIoUnitCntrReply =
5075            (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5076        if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5077                printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5078                    __func__, sasIoUnitCntrReply->IOCStatus,
5079                    sasIoUnitCntrReply->IOCLogInfo);
5080                printk(KERN_DEBUG "%s: failed\n", __func__);
5081                ret = -1;
5082        } else
5083                printk(KERN_DEBUG "%s: success\n", __func__);
5084 out:
5085
5086        CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5087        mutex_unlock(&ioc->mptbase_cmds.mutex);
5088        return ret;
5089}
5090
5091/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5092
5093static void
5094mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5095    MpiEventDataRaid_t * pRaidEventData)
5096{
5097        int     volume;
5098        int     reason;
5099        int     disk;
5100        int     status;
5101        int     flags;
5102        int     state;
5103
5104        volume  = pRaidEventData->VolumeID;
5105        reason  = pRaidEventData->ReasonCode;
5106        disk    = pRaidEventData->PhysDiskNum;
5107        status  = le32_to_cpu(pRaidEventData->SettingsStatus);
5108        flags   = (status >> 0) & 0xff;
5109        state   = (status >> 8) & 0xff;
5110
5111        if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5112                return;
5113        }
5114
5115        if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5116             reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5117            (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5118                printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5119                        ioc->name, disk, volume);
5120        } else {
5121                printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5122                        ioc->name, volume);
5123        }
5124
5125        switch(reason) {
5126        case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5127                printk(MYIOC_s_INFO_FMT "  volume has been created\n",
5128                        ioc->name);
5129                break;
5130
5131        case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5132
5133                printk(MYIOC_s_INFO_FMT "  volume has been deleted\n",
5134                        ioc->name);
5135                break;
5136
5137        case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5138                printk(MYIOC_s_INFO_FMT "  volume settings have been changed\n",
5139                        ioc->name);
5140                break;
5141
5142        case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5143                printk(MYIOC_s_INFO_FMT "  volume is now %s%s%s%s\n",
5144                        ioc->name,
5145                        state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5146                         ? "optimal"
5147                         : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5148                          ? "degraded"
5149                          : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5150                           ? "failed"
5151                           : "state unknown",
5152                        flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5153                         ? ", enabled" : "",
5154                        flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5155                         ? ", quiesced" : "",
5156                        flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5157                         ? ", resync in progress" : "" );
5158                break;
5159
5160        case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5161                printk(MYIOC_s_INFO_FMT "  volume membership of PhysDisk %d has changed\n",
5162                        ioc->name, disk);
5163                break;
5164
5165        case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5166                printk(MYIOC_s_INFO_FMT "  PhysDisk has been created\n",
5167                        ioc->name);
5168                break;
5169
5170        case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5171                printk(MYIOC_s_INFO_FMT "  PhysDisk has been deleted\n",
5172                        ioc->name);
5173                break;
5174
5175        case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5176                printk(MYIOC_s_INFO_FMT "  PhysDisk settings have been changed\n",
5177                        ioc->name);
5178                break;
5179
5180        case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5181                printk(MYIOC_s_INFO_FMT "  PhysDisk is now %s%s%s\n",
5182                        ioc->name,
5183                        state == MPI_PHYSDISK0_STATUS_ONLINE
5184                         ? "online"
5185                         : state == MPI_PHYSDISK0_STATUS_MISSING
5186                          ? "missing"
5187                          : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5188                           ? "not compatible"
5189                           : state == MPI_PHYSDISK0_STATUS_FAILED
5190                            ? "failed"
5191                            : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5192                             ? "initializing"
5193                             : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5194                              ? "offline requested"
5195                              : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5196                               ? "failed requested"
5197                               : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5198                                ? "offline"
5199                                : "state unknown",
5200                        flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5201                         ? ", out of sync" : "",
5202                        flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5203                         ? ", quiesced" : "" );
5204                break;
5205
5206        case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5207                printk(MYIOC_s_INFO_FMT "  Domain Validation needed for PhysDisk %d\n",
5208                        ioc->name, disk);
5209                break;
5210
5211        case MPI_EVENT_RAID_RC_SMART_DATA:
5212                printk(MYIOC_s_INFO_FMT "  SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5213                        ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5214                break;
5215
5216        case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5217                printk(MYIOC_s_INFO_FMT "  replacement of PhysDisk %d has started\n",
5218                        ioc->name, disk);
5219                break;
5220        }
5221}
5222
5223/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5224/**
5225 *      GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5226 *      @ioc: Pointer to MPT_ADAPTER structure
5227 *
5228 *      Returns: 0 for success
5229 *      -ENOMEM if no memory available
5230 *              -EPERM if not allowed due to ISR context
5231 *              -EAGAIN if no msg frames currently available
5232 *              -EFAULT for non-successful reply or no reply (timeout)
5233 */
5234static int
5235GetIoUnitPage2(MPT_ADAPTER *ioc)
5236{
5237        ConfigPageHeader_t       hdr;
5238        CONFIGPARMS              cfg;
5239        IOUnitPage2_t           *ppage_alloc;
5240        dma_addr_t               page_dma;
5241        int                      data_sz;
5242        int                      rc;
5243
5244        /* Get the page header */
5245        hdr.PageVersion = 0;
5246        hdr.PageLength = 0;
5247        hdr.PageNumber = 2;
5248        hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5249        cfg.cfghdr.hdr = &hdr;
5250        cfg.physAddr = -1;
5251        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5252        cfg.dir = 0;
5253        cfg.pageAddr = 0;
5254        cfg.timeout = 0;
5255
5256        if ((rc = mpt_config(ioc, &cfg)) != 0)
5257                return rc;
5258
5259        if (hdr.PageLength == 0)
5260                return 0;
5261
5262        /* Read the config page */
5263        data_sz = hdr.PageLength * 4;
5264        rc = -ENOMEM;
5265        ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5266        if (ppage_alloc) {
5267                memset((u8 *)ppage_alloc, 0, data_sz);
5268                cfg.physAddr = page_dma;
5269                cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5270
5271                /* If Good, save data */
5272                if ((rc = mpt_config(ioc, &cfg)) == 0)
5273                        ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5274
5275                pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5276        }
5277
5278        return rc;
5279}
5280
5281/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5282/**
5283 *      mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5284 *      @ioc: Pointer to a Adapter Strucutre
5285 *      @portnum: IOC port number
5286 *
5287 *      Return: -EFAULT if read of config page header fails
5288 *                      or if no nvram
5289 *      If read of SCSI Port Page 0 fails,
5290 *              NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
5291 *              Adapter settings: async, narrow
5292 *              Return 1
5293 *      If read of SCSI Port Page 2 fails,
5294 *              Adapter settings valid
5295 *              NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
5296 *              Return 1
5297 *      Else
5298 *              Both valid
5299 *              Return 0
5300 *      CHECK - what type of locking mechanisms should be used????
5301 */
5302static int
5303mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5304{
5305        u8                      *pbuf;
5306        dma_addr_t               buf_dma;
5307        CONFIGPARMS              cfg;
5308        ConfigPageHeader_t       header;
5309        int                      ii;
5310        int                      data, rc = 0;
5311
5312        /* Allocate memory
5313         */
5314        if (!ioc->spi_data.nvram) {
5315                int      sz;
5316                u8      *mem;
5317                sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5318                mem = kmalloc(sz, GFP_ATOMIC);
5319                if (mem == NULL)
5320                        return -EFAULT;
5321
5322                ioc->spi_data.nvram = (int *) mem;
5323
5324                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5325                        ioc->name, ioc->spi_data.nvram, sz));
5326        }
5327
5328        /* Invalidate NVRAM information
5329         */
5330        for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5331                ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5332        }
5333
5334        /* Read SPP0 header, allocate memory, then read page.
5335         */
5336        header.PageVersion = 0;
5337        header.PageLength = 0;
5338        header.PageNumber = 0;
5339        header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5340        cfg.cfghdr.hdr = &header;
5341        cfg.physAddr = -1;
5342        cfg.pageAddr = portnum;
5343        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5344        cfg.dir = 0;
5345        cfg.timeout = 0;        /* use default */
5346        if (mpt_config(ioc, &cfg) != 0)
5347                 return -EFAULT;
5348
5349        if (header.PageLength > 0) {
5350                pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5351                if (pbuf) {
5352                        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5353                        cfg.physAddr = buf_dma;
5354                        if (mpt_config(ioc, &cfg) != 0) {
5355                                ioc->spi_data.maxBusWidth = MPT_NARROW;
5356                                ioc->spi_data.maxSyncOffset = 0;
5357                                ioc->spi_data.minSyncFactor = MPT_ASYNC;
5358                                ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5359                                rc = 1;
5360                                ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5361                                        "Unable to read PortPage0 minSyncFactor=%x\n",
5362                                        ioc->name, ioc->spi_data.minSyncFactor));
5363                        } else {
5364                                /* Save the Port Page 0 data
5365                                 */
5366                                SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
5367                                pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5368                                pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5369
5370                                if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5371                                        ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5372                                        ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5373                                                "noQas due to Capabilities=%x\n",
5374                                                ioc->name, pPP0->Capabilities));
5375                                }
5376                                ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5377                                data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5378                                if (data) {
5379                                        ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5380                                        data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5381                                        ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5382                                        ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5383                                                "PortPage0 minSyncFactor=%x\n",
5384                                                ioc->name, ioc->spi_data.minSyncFactor));
5385                                } else {
5386                                        ioc->spi_data.maxSyncOffset = 0;
5387                                        ioc->spi_data.minSyncFactor = MPT_ASYNC;
5388                                }
5389
5390                                ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5391
5392                                /* Update the minSyncFactor based on bus type.
5393                                 */
5394                                if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5395                                        (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
5396
5397                                        if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5398                                                ioc->spi_data.minSyncFactor = MPT_ULTRA;
5399                                                ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5400                                                        "HVD or SE detected, minSyncFactor=%x\n",
5401                                                        ioc->name, ioc->spi_data.minSyncFactor));
5402                                        }
5403                                }
5404                        }
5405                        if (pbuf) {
5406                                pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5407                        }
5408                }
5409        }
5410
5411        /* SCSI Port Page 2 - Read the header then the page.
5412         */
5413        header.PageVersion = 0;
5414        header.PageLength = 0;
5415        header.PageNumber = 2;
5416        header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5417        cfg.cfghdr.hdr = &header;
5418        cfg.physAddr = -1;
5419        cfg.pageAddr = portnum;
5420        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5421        cfg.dir = 0;
5422        if (mpt_config(ioc, &cfg) != 0)
5423                return -EFAULT;
5424
5425        if (header.PageLength > 0) {
5426                /* Allocate memory and read SCSI Port Page 2
5427                 */
5428                pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5429                if (pbuf) {
5430                        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5431                        cfg.physAddr = buf_dma;
5432                        if (mpt_config(ioc, &cfg) != 0) {
5433                                /* Nvram data is left with INVALID mark
5434                                 */
5435                                rc = 1;
5436                        } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5437
5438                                /* This is an ATTO adapter, read Page2 accordingly
5439                                */
5440                                ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t  *) pbuf;
5441                                ATTODeviceInfo_t *pdevice = NULL;
5442                                u16 ATTOFlags;
5443
5444                                /* Save the Port Page 2 data
5445                                 * (reformat into a 32bit quantity)
5446                                 */
5447                                for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5448                                  pdevice = &pPP2->DeviceSettings[ii];
5449                                  ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5450                                  data = 0;
5451
5452                                  /* Translate ATTO device flags to LSI format
5453                                   */
5454                                  if (ATTOFlags & ATTOFLAG_DISC)
5455                                    data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5456                                  if (ATTOFlags & ATTOFLAG_ID_ENB)
5457                                    data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5458                                  if (ATTOFlags & ATTOFLAG_LUN_ENB)
5459                                    data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5460                                  if (ATTOFlags & ATTOFLAG_TAGGED)
5461                                    data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5462                                  if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5463                                    data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5464
5465                                  data = (data << 16) | (pdevice->Period << 8) | 10;
5466                                  ioc->spi_data.nvram[ii] = data;
5467                                }
5468                        } else {
5469                                SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
5470                                MpiDeviceInfo_t *pdevice = NULL;
5471
5472                                /*
5473                                 * Save "Set to Avoid SCSI Bus Resets" flag
5474                                 */
5475                                ioc->spi_data.bus_reset =
5476                                    (le32_to_cpu(pPP2->PortFlags) &
5477                                MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5478                                    0 : 1 ;
5479
5480                                /* Save the Port Page 2 data
5481                                 * (reformat into a 32bit quantity)
5482                                 */
5483                                data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5484                                ioc->spi_data.PortFlags = data;
5485                                for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5486                                        pdevice = &pPP2->DeviceSettings[ii];
5487                                        data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5488                                                (pdevice->SyncFactor << 8) | pdevice->Timeout;
5489                                        ioc->spi_data.nvram[ii] = data;
5490                                }
5491                        }
5492
5493                        pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5494                }
5495        }
5496
5497        /* Update Adapter limits with those from NVRAM
5498         * Comment: Don't need to do this. Target performance
5499         * parameters will never exceed the adapters limits.
5500         */
5501
5502        return rc;
5503}
5504
5505/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5506/**
5507 *      mpt_readScsiDevicePageHeaders - save version and length of SDP1
5508 *      @ioc: Pointer to a Adapter Strucutre
5509 *      @portnum: IOC port number
5510 *
5511 *      Return: -EFAULT if read of config page header fails
5512 *              or 0 if success.
5513 */
5514static int
5515mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5516{
5517        CONFIGPARMS              cfg;
5518        ConfigPageHeader_t       header;
5519
5520        /* Read the SCSI Device Page 1 header
5521         */
5522        header.PageVersion = 0;
5523        header.PageLength = 0;
5524        header.PageNumber = 1;
5525        header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5526        cfg.cfghdr.hdr = &header;
5527        cfg.physAddr = -1;
5528        cfg.pageAddr = portnum;
5529        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5530        cfg.dir = 0;
5531        cfg.timeout = 0;
5532        if (mpt_config(ioc, &cfg) != 0)
5533                 return -EFAULT;
5534
5535        ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5536        ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5537
5538        header.PageVersion = 0;
5539        header.PageLength = 0;
5540        header.PageNumber = 0;
5541        header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5542        if (mpt_config(ioc, &cfg) != 0)
5543                 return -EFAULT;
5544
5545        ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5546        ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5547
5548        dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5549                        ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5550
5551        dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5552                        ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5553        return 0;
5554}
5555
5556/**
5557 * mpt_inactive_raid_list_free - This clears this link list.
5558 * @ioc : pointer to per adapter structure
5559 **/
5560static void
5561mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5562{
5563        struct inactive_raid_component_info *component_info, *pNext;
5564
5565        if (list_empty(&ioc->raid_data.inactive_list))
5566                return;
5567
5568        mutex_lock(&ioc->raid_data.inactive_list_mutex);
5569        list_for_each_entry_safe(component_info, pNext,
5570            &ioc->raid_data.inactive_list, list) {
5571                list_del(&component_info->list);
5572                kfree(component_info);
5573        }
5574        mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5575}
5576
5577/**
5578 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5579 *
5580 * @ioc : pointer to per adapter structure
5581 * @channel : volume channel
5582 * @id : volume target id
5583 **/
5584static void
5585mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5586{
5587        CONFIGPARMS                     cfg;
5588        ConfigPageHeader_t              hdr;
5589        dma_addr_t                      dma_handle;
5590        pRaidVolumePage0_t              buffer = NULL;
5591        int                             i;
5592        RaidPhysDiskPage0_t             phys_disk;
5593        struct inactive_raid_component_info *component_info;
5594        int                             handle_inactive_volumes;
5595
5596        memset(&cfg, 0 , sizeof(CONFIGPARMS));
5597        memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5598        hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5599        cfg.pageAddr = (channel << 8) + id;
5600        cfg.cfghdr.hdr = &hdr;
5601        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5602
5603        if (mpt_config(ioc, &cfg) != 0)
5604                goto out;
5605
5606        if (!hdr.PageLength)
5607                goto out;
5608
5609        buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5610            &dma_handle);
5611
5612        if (!buffer)
5613                goto out;
5614
5615        cfg.physAddr = dma_handle;
5616        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5617
5618        if (mpt_config(ioc, &cfg) != 0)
5619                goto out;
5620
5621        if (!buffer->NumPhysDisks)
5622                goto out;
5623
5624        handle_inactive_volumes =
5625           (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5626           (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5627            buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5628            buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5629
5630        if (!handle_inactive_volumes)
5631                goto out;
5632
5633        mutex_lock(&ioc->raid_data.inactive_list_mutex);
5634        for (i = 0; i < buffer->NumPhysDisks; i++) {
5635                if(mpt_raid_phys_disk_pg0(ioc,
5636                    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5637                        continue;
5638
5639                if ((component_info = kmalloc(sizeof (*component_info),
5640                 GFP_KERNEL)) == NULL)
5641                        continue;
5642
5643                component_info->volumeID = id;
5644                component_info->volumeBus = channel;
5645                component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5646                component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5647                component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5648                component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5649
5650                list_add_tail(&component_info->list,
5651                    &ioc->raid_data.inactive_list);
5652        }
5653        mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5654
5655 out:
5656        if (buffer)
5657                pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5658                    dma_handle);
5659}
5660
5661/**
5662 *      mpt_raid_phys_disk_pg0 - returns phys disk page zero
5663 *      @ioc: Pointer to a Adapter Structure
5664 *      @phys_disk_num: io unit unique phys disk num generated by the ioc
5665 *      @phys_disk: requested payload data returned
5666 *
5667 *      Return:
5668 *      0 on success
5669 *      -EFAULT if read of config page header fails or data pointer not NULL
5670 *      -ENOMEM if pci_alloc failed
5671 **/
5672int
5673mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5674                        RaidPhysDiskPage0_t *phys_disk)
5675{
5676        CONFIGPARMS                     cfg;
5677        ConfigPageHeader_t              hdr;
5678        dma_addr_t                      dma_handle;
5679        pRaidPhysDiskPage0_t            buffer = NULL;
5680        int                             rc;
5681
5682        memset(&cfg, 0 , sizeof(CONFIGPARMS));
5683        memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5684        memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5685
5686        hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5687        hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5688        cfg.cfghdr.hdr = &hdr;
5689        cfg.physAddr = -1;
5690        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5691
5692        if (mpt_config(ioc, &cfg) != 0) {
5693                rc = -EFAULT;
5694                goto out;
5695        }
5696
5697        if (!hdr.PageLength) {
5698                rc = -EFAULT;
5699                goto out;
5700        }
5701
5702        buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5703            &dma_handle);
5704
5705        if (!buffer) {
5706                rc = -ENOMEM;
5707                goto out;
5708        }
5709
5710        cfg.physAddr = dma_handle;
5711        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5712        cfg.pageAddr = phys_disk_num;
5713
5714        if (mpt_config(ioc, &cfg) != 0) {
5715                rc = -EFAULT;
5716                goto out;
5717        }
5718
5719        rc = 0;
5720        memcpy(phys_disk, buffer, sizeof(*buffer));
5721        phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5722
5723 out:
5724
5725        if (buffer)
5726                pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5727                    dma_handle);
5728
5729        return rc;
5730}
5731
5732/**
5733 *      mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5734 *      @ioc: Pointer to a Adapter Structure
5735 *      @phys_disk_num: io unit unique phys disk num generated by the ioc
5736 *
5737 *      Return:
5738 *      returns number paths
5739 **/
5740int
5741mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5742{
5743        CONFIGPARMS                     cfg;
5744        ConfigPageHeader_t              hdr;
5745        dma_addr_t                      dma_handle;
5746        pRaidPhysDiskPage1_t            buffer = NULL;
5747        int                             rc;
5748
5749        memset(&cfg, 0 , sizeof(CONFIGPARMS));
5750        memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5751
5752        hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5753        hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5754        hdr.PageNumber = 1;
5755        cfg.cfghdr.hdr = &hdr;
5756        cfg.physAddr = -1;
5757        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5758
5759        if (mpt_config(ioc, &cfg) != 0) {
5760                rc = 0;
5761                goto out;
5762        }
5763
5764        if (!hdr.PageLength) {
5765                rc = 0;
5766                goto out;
5767        }
5768
5769        buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5770            &dma_handle);
5771
5772        if (!buffer) {
5773                rc = 0;
5774                goto out;
5775        }
5776
5777        cfg.physAddr = dma_handle;
5778        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5779        cfg.pageAddr = phys_disk_num;
5780
5781        if (mpt_config(ioc, &cfg) != 0) {
5782                rc = 0;
5783                goto out;
5784        }
5785
5786        rc = buffer->NumPhysDiskPaths;
5787 out:
5788
5789        if (buffer)
5790                pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5791                    dma_handle);
5792
5793        return rc;
5794}
5795EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5796
5797/**
5798 *      mpt_raid_phys_disk_pg1 - returns phys disk page 1
5799 *      @ioc: Pointer to a Adapter Structure
5800 *      @phys_disk_num: io unit unique phys disk num generated by the ioc
5801 *      @phys_disk: requested payload data returned
5802 *
5803 *      Return:
5804 *      0 on success
5805 *      -EFAULT if read of config page header fails or data pointer not NULL
5806 *      -ENOMEM if pci_alloc failed
5807 **/
5808int
5809mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5810                RaidPhysDiskPage1_t *phys_disk)
5811{
5812        CONFIGPARMS                     cfg;
5813        ConfigPageHeader_t              hdr;
5814        dma_addr_t                      dma_handle;
5815        pRaidPhysDiskPage1_t            buffer = NULL;
5816        int                             rc;
5817        int                             i;
5818        __le64                          sas_address;
5819
5820        memset(&cfg, 0 , sizeof(CONFIGPARMS));
5821        memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5822        rc = 0;
5823
5824        hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5825        hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5826        hdr.PageNumber = 1;
5827        cfg.cfghdr.hdr = &hdr;
5828        cfg.physAddr = -1;
5829        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5830
5831        if (mpt_config(ioc, &cfg) != 0) {
5832                rc = -EFAULT;
5833                goto out;
5834        }
5835
5836        if (!hdr.PageLength) {
5837                rc = -EFAULT;
5838                goto out;
5839        }
5840
5841        buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5842            &dma_handle);
5843
5844        if (!buffer) {
5845                rc = -ENOMEM;
5846                goto out;
5847        }
5848
5849        cfg.physAddr = dma_handle;
5850        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5851        cfg.pageAddr = phys_disk_num;
5852
5853        if (mpt_config(ioc, &cfg) != 0) {
5854                rc = -EFAULT;
5855                goto out;
5856        }
5857
5858        phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5859        phys_disk->PhysDiskNum = phys_disk_num;
5860        for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5861                phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5862                phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5863                phys_disk->Path[i].OwnerIdentifier =
5864                                buffer->Path[i].OwnerIdentifier;
5865                phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5866                memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5867                sas_address = le64_to_cpu(sas_address);
5868                memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5869                memcpy(&sas_address,
5870                                &buffer->Path[i].OwnerWWID, sizeof(__le64));
5871                sas_address = le64_to_cpu(sas_address);
5872                memcpy(&phys_disk->Path[i].OwnerWWID,
5873                                &sas_address, sizeof(__le64));
5874        }
5875
5876 out:
5877
5878        if (buffer)
5879                pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5880                    dma_handle);
5881
5882        return rc;
5883}
5884EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5885
5886
5887/**
5888 *      mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5889 *      @ioc: Pointer to a Adapter Strucutre
5890 *
5891 *      Return:
5892 *      0 on success
5893 *      -EFAULT if read of config page header fails or data pointer not NULL
5894 *      -ENOMEM if pci_alloc failed
5895 **/
5896int
5897mpt_findImVolumes(MPT_ADAPTER *ioc)
5898{
5899        IOCPage2_t              *pIoc2;
5900        u8                      *mem;
5901        dma_addr_t               ioc2_dma;
5902        CONFIGPARMS              cfg;
5903        ConfigPageHeader_t       header;
5904        int                      rc = 0;
5905        int                      iocpage2sz;
5906        int                      i;
5907
5908        if (!ioc->ir_firmware)
5909                return 0;
5910
5911        /* Free the old page
5912         */
5913        kfree(ioc->raid_data.pIocPg2);
5914        ioc->raid_data.pIocPg2 = NULL;
5915        mpt_inactive_raid_list_free(ioc);
5916
5917        /* Read IOCP2 header then the page.
5918         */
5919        header.PageVersion = 0;
5920        header.PageLength = 0;
5921        header.PageNumber = 2;
5922        header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5923        cfg.cfghdr.hdr = &header;
5924        cfg.physAddr = -1;
5925        cfg.pageAddr = 0;
5926        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5927        cfg.dir = 0;
5928        cfg.timeout = 0;
5929        if (mpt_config(ioc, &cfg) != 0)
5930                 return -EFAULT;
5931
5932        if (header.PageLength == 0)
5933                return -EFAULT;
5934
5935        iocpage2sz = header.PageLength * 4;
5936        pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5937        if (!pIoc2)
5938                return -ENOMEM;
5939
5940        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5941        cfg.physAddr = ioc2_dma;
5942        if (mpt_config(ioc, &cfg) != 0)
5943                goto out;
5944
5945        mem = kmalloc(iocpage2sz, GFP_KERNEL);
5946        if (!mem) {
5947                rc = -ENOMEM;
5948                goto out;
5949        }
5950
5951        memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5952        ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5953
5954        mpt_read_ioc_pg_3(ioc);
5955
5956        for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5957                mpt_inactive_raid_volumes(ioc,
5958                    pIoc2->RaidVolume[i].VolumeBus,
5959                    pIoc2->RaidVolume[i].VolumeID);
5960
5961 out:
5962        pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5963
5964        return rc;
5965}
5966
5967static int
5968mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5969{
5970        IOCPage3_t              *pIoc3;
5971        u8                      *mem;
5972        CONFIGPARMS              cfg;
5973        ConfigPageHeader_t       header;
5974        dma_addr_t               ioc3_dma;
5975        int                      iocpage3sz = 0;
5976
5977        /* Free the old page
5978         */
5979        kfree(ioc->raid_data.pIocPg3);
5980        ioc->raid_data.pIocPg3 = NULL;
5981
5982        /* There is at least one physical disk.
5983         * Read and save IOC Page 3
5984         */
5985        header.PageVersion = 0;
5986        header.PageLength = 0;
5987        header.PageNumber = 3;
5988        header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5989        cfg.cfghdr.hdr = &header;
5990        cfg.physAddr = -1;
5991        cfg.pageAddr = 0;
5992        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5993        cfg.dir = 0;
5994        cfg.timeout = 0;
5995        if (mpt_config(ioc, &cfg) != 0)
5996                return 0;
5997
5998        if (header.PageLength == 0)
5999                return 0;
6000
6001        /* Read Header good, alloc memory
6002         */
6003        iocpage3sz = header.PageLength * 4;
6004        pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6005        if (!pIoc3)
6006                return 0;
6007
6008        /* Read the Page and save the data
6009         * into malloc'd memory.
6010         */
6011        cfg.physAddr = ioc3_dma;
6012        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6013        if (mpt_config(ioc, &cfg) == 0) {
6014                mem = kmalloc(iocpage3sz, GFP_KERNEL);
6015                if (mem) {
6016                        memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6017                        ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6018                }
6019        }
6020
6021        pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6022
6023        return 0;
6024}
6025
6026static void
6027mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6028{
6029        IOCPage4_t              *pIoc4;
6030        CONFIGPARMS              cfg;
6031        ConfigPageHeader_t       header;
6032        dma_addr_t               ioc4_dma;
6033        int                      iocpage4sz;
6034
6035        /* Read and save IOC Page 4
6036         */
6037        header.PageVersion = 0;
6038        header.PageLength = 0;
6039        header.PageNumber = 4;
6040        header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6041        cfg.cfghdr.hdr = &header;
6042        cfg.physAddr = -1;
6043        cfg.pageAddr = 0;
6044        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6045        cfg.dir = 0;
6046        cfg.timeout = 0;
6047        if (mpt_config(ioc, &cfg) != 0)
6048                return;
6049
6050        if (header.PageLength == 0)
6051                return;
6052
6053        if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6054                iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6055                pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6056                if (!pIoc4)
6057                        return;
6058                ioc->alloc_total += iocpage4sz;
6059        } else {
6060                ioc4_dma = ioc->spi_data.IocPg4_dma;
6061                iocpage4sz = ioc->spi_data.IocPg4Sz;
6062        }
6063
6064        /* Read the Page into dma memory.
6065         */
6066        cfg.physAddr = ioc4_dma;
6067        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6068        if (mpt_config(ioc, &cfg) == 0) {
6069                ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6070                ioc->spi_data.IocPg4_dma = ioc4_dma;
6071                ioc->spi_data.IocPg4Sz = iocpage4sz;
6072        } else {
6073                pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6074                ioc->spi_data.pIocPg4 = NULL;
6075                ioc->alloc_total -= iocpage4sz;
6076        }
6077}
6078
6079static void
6080mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6081{
6082        IOCPage1_t              *pIoc1;
6083        CONFIGPARMS              cfg;
6084        ConfigPageHeader_t       header;
6085        dma_addr_t               ioc1_dma;
6086        int                      iocpage1sz = 0;
6087        u32                      tmp;
6088
6089        /* Check the Coalescing Timeout in IOC Page 1
6090         */
6091        header.PageVersion = 0;
6092        header.PageLength = 0;
6093        header.PageNumber = 1;
6094        header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6095        cfg.cfghdr.hdr = &header;
6096        cfg.physAddr = -1;
6097        cfg.pageAddr = 0;
6098        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6099        cfg.dir = 0;
6100        cfg.timeout = 0;
6101        if (mpt_config(ioc, &cfg) != 0)
6102                return;
6103
6104        if (header.PageLength == 0)
6105                return;
6106
6107        /* Read Header good, alloc memory
6108         */
6109        iocpage1sz = header.PageLength * 4;
6110        pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6111        if (!pIoc1)
6112                return;
6113
6114        /* Read the Page and check coalescing timeout
6115         */
6116        cfg.physAddr = ioc1_dma;
6117        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6118        if (mpt_config(ioc, &cfg) == 0) {
6119
6120                tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6121                if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6122                        tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6123
6124                        dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6125                                        ioc->name, tmp));
6126
6127                        if (tmp > MPT_COALESCING_TIMEOUT) {
6128                                pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6129
6130                                /* Write NVRAM and current
6131                                 */
6132                                cfg.dir = 1;
6133                                cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6134                                if (mpt_config(ioc, &cfg) == 0) {
6135                                        dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6136                                                        ioc->name, MPT_COALESCING_TIMEOUT));
6137
6138                                        cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6139                                        if (mpt_config(ioc, &cfg) == 0) {
6140                                                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6141                                                                "Reset NVRAM Coalescing Timeout to = %d\n",
6142                                                                ioc->name, MPT_COALESCING_TIMEOUT));
6143                                        } else {
6144                                                dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6145                                                                "Reset NVRAM Coalescing Timeout Failed\n",
6146                                                                ioc->name));
6147                                        }
6148
6149                                } else {
6150                                        dprintk(ioc, printk(MYIOC_s_WARN_FMT
6151                                                "Reset of Current Coalescing Timeout Failed!\n",
6152                                                ioc->name));
6153                                }
6154                        }
6155
6156                } else {
6157                        dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6158                }
6159        }
6160
6161        pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6162
6163        return;
6164}
6165
6166static void
6167mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6168{
6169        CONFIGPARMS             cfg;
6170        ConfigPageHeader_t      hdr;
6171        dma_addr_t              buf_dma;
6172        ManufacturingPage0_t    *pbuf = NULL;
6173
6174        memset(&cfg, 0 , sizeof(CONFIGPARMS));
6175        memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6176
6177        hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6178        cfg.cfghdr.hdr = &hdr;
6179        cfg.physAddr = -1;
6180        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6181        cfg.timeout = 10;
6182
6183        if (mpt_config(ioc, &cfg) != 0)
6184                goto out;
6185
6186        if (!cfg.cfghdr.hdr->PageLength)
6187                goto out;
6188
6189        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6190        pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6191        if (!pbuf)
6192                goto out;
6193
6194        cfg.physAddr = buf_dma;
6195
6196        if (mpt_config(ioc, &cfg) != 0)
6197                goto out;
6198
6199        memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6200        memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6201        memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6202
6203        out:
6204
6205        if (pbuf)
6206                pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6207}
6208
6209/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6210/**
6211 *      SendEventNotification - Send EventNotification (on or off) request to adapter
6212 *      @ioc: Pointer to MPT_ADAPTER structure
6213 *      @EvSwitch: Event switch flags
6214 *      @sleepFlag: Specifies whether the process can sleep
6215 */
6216static int
6217SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6218{
6219        EventNotification_t     evn;
6220        MPIDefaultReply_t       reply_buf;
6221
6222        memset(&evn, 0, sizeof(EventNotification_t));
6223        memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6224
6225        evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6226        evn.Switch = EvSwitch;
6227        evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6228
6229        devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6230            "Sending EventNotification (%d) request %p\n",
6231            ioc->name, EvSwitch, &evn));
6232
6233        return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6234            (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6235            sleepFlag);
6236}
6237
6238/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6239/**
6240 *      SendEventAck - Send EventAck request to MPT adapter.
6241 *      @ioc: Pointer to MPT_ADAPTER structure
6242 *      @evnp: Pointer to original EventNotification request
6243 */
6244static int
6245SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6246{
6247        EventAck_t      *pAck;
6248
6249        if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6250                dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6251                    ioc->name, __func__));
6252                return -1;
6253        }
6254
6255        devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6256
6257        pAck->Function     = MPI_FUNCTION_EVENT_ACK;
6258        pAck->ChainOffset  = 0;
6259        pAck->Reserved[0]  = pAck->Reserved[1] = 0;
6260        pAck->MsgFlags     = 0;
6261        pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6262        pAck->Event        = evnp->Event;
6263        pAck->EventContext = evnp->EventContext;
6264
6265        mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6266
6267        return 0;
6268}
6269
6270/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6271/**
6272 *      mpt_config - Generic function to issue config message
6273 *      @ioc:   Pointer to an adapter structure
6274 *      @pCfg:  Pointer to a configuration structure. Struct contains
6275 *              action, page address, direction, physical address
6276 *              and pointer to a configuration page header
6277 *              Page header is updated.
6278 *
6279 *      Returns 0 for success
6280 *      -EPERM if not allowed due to ISR context
6281 *      -EAGAIN if no msg frames currently available
6282 *      -EFAULT for non-successful reply or no reply (timeout)
6283 */
6284int
6285mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6286{
6287        Config_t        *pReq;
6288        ConfigReply_t   *pReply;
6289        ConfigExtendedPageHeader_t  *pExtHdr = NULL;
6290        MPT_FRAME_HDR   *mf;
6291        int              ii;
6292        int              flagsLength;
6293        long             timeout;
6294        int              ret;
6295        u8               page_type = 0, extend_page;
6296        unsigned long    timeleft;
6297        unsigned long    flags;
6298    int          in_isr;
6299        u8               issue_hard_reset = 0;
6300        u8               retry_count = 0;
6301
6302        /*      Prevent calling wait_event() (below), if caller happens
6303         *      to be in ISR context, because that is fatal!
6304         */
6305        in_isr = in_interrupt();
6306        if (in_isr) {
6307                dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6308                                ioc->name));
6309                return -EPERM;
6310    }
6311
6312        /* don't send a config page during diag reset */
6313        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6314        if (ioc->ioc_reset_in_progress) {
6315                dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6316                    "%s: busy with host reset\n", ioc->name, __func__));
6317                spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6318                return -EBUSY;
6319        }
6320        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6321
6322        /* don't send if no chance of success */
6323        if (!ioc->active ||
6324            mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6325                dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6326                    "%s: ioc not operational, %d, %xh\n",
6327                    ioc->name, __func__, ioc->active,
6328                    mpt_GetIocState(ioc, 0)));
6329                return -EFAULT;
6330        }
6331
6332 retry_config:
6333        mutex_lock(&ioc->mptbase_cmds.mutex);
6334        /* init the internal cmd struct */
6335        memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6336        INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6337
6338        /* Get and Populate a free Frame
6339         */
6340        if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6341                dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6342                "mpt_config: no msg frames!\n", ioc->name));
6343                ret = -EAGAIN;
6344                goto out;
6345        }
6346
6347        pReq = (Config_t *)mf;
6348        pReq->Action = pCfg->action;
6349        pReq->Reserved = 0;
6350        pReq->ChainOffset = 0;
6351        pReq->Function = MPI_FUNCTION_CONFIG;
6352
6353        /* Assume page type is not extended and clear "reserved" fields. */
6354        pReq->ExtPageLength = 0;
6355        pReq->ExtPageType = 0;
6356        pReq->MsgFlags = 0;
6357
6358        for (ii=0; ii < 8; ii++)
6359                pReq->Reserved2[ii] = 0;
6360
6361        pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6362        pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6363        pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6364        pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6365
6366        if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6367                pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6368                pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6369                pReq->ExtPageType = pExtHdr->ExtPageType;
6370                pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6371
6372                /* Page Length must be treated as a reserved field for the
6373                 * extended header.
6374                 */
6375                pReq->Header.PageLength = 0;
6376        }
6377
6378        pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6379
6380        /* Add a SGE to the config request.
6381         */
6382        if (pCfg->dir)
6383                flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6384        else
6385                flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6386
6387        if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6388            MPI_CONFIG_PAGETYPE_EXTENDED) {
6389                flagsLength |= pExtHdr->ExtPageLength * 4;
6390                page_type = pReq->ExtPageType;
6391                extend_page = 1;
6392        } else {
6393                flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6394                page_type = pReq->Header.PageType;
6395                extend_page = 0;
6396        }
6397
6398        dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6399            "Sending Config request type 0x%x, page 0x%x and action %d\n",
6400            ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6401
6402        ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6403        timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6404        mpt_put_msg_frame(mpt_base_index, ioc, mf);
6405        timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6406                timeout);
6407        if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6408                ret = -ETIME;
6409                dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6410                    "Failed Sending Config request type 0x%x, page 0x%x,"
6411                    " action %d, status %xh, time left %ld\n\n",
6412                        ioc->name, page_type, pReq->Header.PageNumber,
6413                        pReq->Action, ioc->mptbase_cmds.status, timeleft));
6414                if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6415                        goto out;
6416                if (!timeleft)
6417                        issue_hard_reset = 1;
6418                goto out;
6419        }
6420
6421        if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6422                ret = -1;
6423                goto out;
6424        }
6425        pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6426        ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6427        if (ret == MPI_IOCSTATUS_SUCCESS) {
6428                if (extend_page) {
6429                        pCfg->cfghdr.ehdr->ExtPageLength =
6430                            le16_to_cpu(pReply->ExtPageLength);
6431                        pCfg->cfghdr.ehdr->ExtPageType =
6432                            pReply->ExtPageType;
6433                }
6434                pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6435                pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6436                pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6437                pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6438
6439        }
6440
6441        if (retry_count)
6442                printk(MYIOC_s_INFO_FMT "Retry completed "
6443                    "ret=0x%x timeleft=%ld\n",
6444                    ioc->name, ret, timeleft);
6445
6446        dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6447             ret, le32_to_cpu(pReply->IOCLogInfo)));
6448
6449out:
6450
6451        CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6452        mutex_unlock(&ioc->mptbase_cmds.mutex);
6453        if (issue_hard_reset) {
6454                issue_hard_reset = 0;
6455                printk(MYIOC_s_WARN_FMT
6456                       "Issuing Reset from %s!!, doorbell=0x%08x\n",
6457                       ioc->name, __func__, mpt_GetIocState(ioc, 0));
6458                if (retry_count == 0) {
6459                        if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6460                                retry_count++;
6461                } else
6462                        mpt_HardResetHandler(ioc, CAN_SLEEP);
6463
6464                mpt_free_msg_frame(ioc, mf);
6465                /* attempt one retry for a timed out command */
6466                if (retry_count < 2) {
6467                        printk(MYIOC_s_INFO_FMT
6468                            "Attempting Retry Config request"
6469                            " type 0x%x, page 0x%x,"
6470                            " action %d\n", ioc->name, page_type,
6471                            pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6472                        retry_count++;
6473                        goto retry_config;
6474                }
6475        }
6476        return ret;
6477
6478}
6479
6480/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6481/**
6482 *      mpt_ioc_reset - Base cleanup for hard reset
6483 *      @ioc: Pointer to the adapter structure
6484 *      @reset_phase: Indicates pre- or post-reset functionality
6485 *
6486 *      Remark: Frees resources with internally generated commands.
6487 */
6488static int
6489mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6490{
6491        switch (reset_phase) {
6492        case MPT_IOC_SETUP_RESET:
6493                ioc->taskmgmt_quiesce_io = 1;
6494                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6495                    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6496                break;
6497        case MPT_IOC_PRE_RESET:
6498                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6499                    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6500                break;
6501        case MPT_IOC_POST_RESET:
6502                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6503                    "%s: MPT_IOC_POST_RESET\n",  ioc->name, __func__));
6504/* wake up mptbase_cmds */
6505                if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6506                        ioc->mptbase_cmds.status |=
6507                            MPT_MGMT_STATUS_DID_IOCRESET;
6508                        complete(&ioc->mptbase_cmds.done);
6509                }
6510/* wake up taskmgmt_cmds */
6511                if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6512                        ioc->taskmgmt_cmds.status |=
6513                                MPT_MGMT_STATUS_DID_IOCRESET;
6514                        complete(&ioc->taskmgmt_cmds.done);
6515                }
6516                break;
6517        default:
6518                break;
6519        }
6520
6521        return 1;               /* currently means nothing really */
6522}
6523
6524
6525#ifdef CONFIG_PROC_FS           /* { */
6526/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6527/*
6528 *      procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6529 */
6530/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6531/**
6532 *      procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6533 *
6534 *      Returns 0 for success, non-zero for failure.
6535 */
6536static int
6537procmpt_create(void)
6538{
6539        mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6540        if (mpt_proc_root_dir == NULL)
6541                return -ENOTDIR;
6542
6543        proc_create("summary", S_IRUGO, mpt_proc_root_dir, &mpt_summary_proc_fops);
6544        proc_create("version", S_IRUGO, mpt_proc_root_dir, &mpt_version_proc_fops);
6545        return 0;
6546}
6547
6548/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6549/**
6550 *      procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6551 *
6552 *      Returns 0 for success, non-zero for failure.
6553 */
6554static void
6555procmpt_destroy(void)
6556{
6557        remove_proc_entry("version", mpt_proc_root_dir);
6558        remove_proc_entry("summary", mpt_proc_root_dir);
6559        remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6560}
6561
6562/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6563/*
6564 *      Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6565 */
6566static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6567
6568static int mpt_summary_proc_show(struct seq_file *m, void *v)
6569{
6570        MPT_ADAPTER *ioc = m->private;
6571
6572        if (ioc) {
6573                seq_mpt_print_ioc_summary(ioc, m, 1);
6574        } else {
6575                list_for_each_entry(ioc, &ioc_list, list) {
6576                        seq_mpt_print_ioc_summary(ioc, m, 1);
6577                }
6578        }
6579
6580        return 0;
6581}
6582
6583static int mpt_summary_proc_open(struct inode *inode, struct file *file)
6584{
6585        return single_open(file, mpt_summary_proc_show, PDE(inode)->data);
6586}
6587
6588static const struct file_operations mpt_summary_proc_fops = {
6589        .owner          = THIS_MODULE,
6590        .open           = mpt_summary_proc_open,
6591        .read           = seq_read,
6592        .llseek         = seq_lseek,
6593        .release        = single_release,
6594};
6595
6596static int mpt_version_proc_show(struct seq_file *m, void *v)
6597{
6598        u8       cb_idx;
6599        int      scsi, fc, sas, lan, ctl, targ, dmp;
6600        char    *drvname;
6601
6602        seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6603        seq_printf(m, "  Fusion MPT base driver\n");
6604
6605        scsi = fc = sas = lan = ctl = targ = dmp = 0;
6606        for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6607                drvname = NULL;
6608                if (MptCallbacks[cb_idx]) {
6609                        switch (MptDriverClass[cb_idx]) {
6610                        case MPTSPI_DRIVER:
6611                                if (!scsi++) drvname = "SPI host";
6612                                break;
6613                        case MPTFC_DRIVER:
6614                                if (!fc++) drvname = "FC host";
6615                                break;
6616                        case MPTSAS_DRIVER:
6617                                if (!sas++) drvname = "SAS host";
6618                                break;
6619                        case MPTLAN_DRIVER:
6620                                if (!lan++) drvname = "LAN";
6621                                break;
6622                        case MPTSTM_DRIVER:
6623                                if (!targ++) drvname = "SCSI target";
6624                                break;
6625                        case MPTCTL_DRIVER:
6626                                if (!ctl++) drvname = "ioctl";
6627                                break;
6628                        }
6629
6630                        if (drvname)
6631                                seq_printf(m, "  Fusion MPT %s driver\n", drvname);
6632                }
6633        }
6634
6635        return 0;
6636}
6637
6638static int mpt_version_proc_open(struct inode *inode, struct file *file)
6639{
6640        return single_open(file, mpt_version_proc_show, NULL);
6641}
6642
6643static const struct file_operations mpt_version_proc_fops = {
6644        .owner          = THIS_MODULE,
6645        .open           = mpt_version_proc_open,
6646        .read           = seq_read,
6647        .llseek         = seq_lseek,
6648        .release        = single_release,
6649};
6650
6651static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
6652{
6653        MPT_ADAPTER     *ioc = m->private;
6654        char             expVer[32];
6655        int              sz;
6656        int              p;
6657
6658        mpt_get_fw_exp_ver(expVer, ioc);
6659
6660        seq_printf(m, "%s:", ioc->name);
6661        if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6662                seq_printf(m, "  (f/w download boot flag set)");
6663//      if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6664//              seq_printf(m, "  CONFIG_CHECKSUM_FAIL!");
6665
6666        seq_printf(m, "\n  ProductID = 0x%04x (%s)\n",
6667                        ioc->facts.ProductID,
6668                        ioc->prod_name);
6669        seq_printf(m, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6670        if (ioc->facts.FWImageSize)
6671                seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
6672        seq_printf(m, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6673        seq_printf(m, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6674        seq_printf(m, "  EventState = 0x%02x\n", ioc->facts.EventState);
6675
6676        seq_printf(m, "  CurrentHostMfaHighAddr = 0x%08x\n",
6677                        ioc->facts.CurrentHostMfaHighAddr);
6678        seq_printf(m, "  CurrentSenseBufferHighAddr = 0x%08x\n",
6679                        ioc->facts.CurrentSenseBufferHighAddr);
6680
6681        seq_printf(m, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6682        seq_printf(m, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6683
6684        seq_printf(m, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6685                                        (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6686        /*
6687         *  Rounding UP to nearest 4-kB boundary here...
6688         */
6689        sz = (ioc->req_sz * ioc->req_depth) + 128;
6690        sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6691        seq_printf(m, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6692                                        ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6693        seq_printf(m, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
6694                                        4*ioc->facts.RequestFrameSize,
6695                                        ioc->facts.GlobalCredits);
6696
6697        seq_printf(m, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
6698                                        (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6699        sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6700        seq_printf(m, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6701                                        ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6702        seq_printf(m, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
6703                                        ioc->facts.CurReplyFrameSize,
6704                                        ioc->facts.ReplyQueueDepth);
6705
6706        seq_printf(m, "  MaxDevices = %d\n",
6707                        (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6708        seq_printf(m, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
6709
6710        /* per-port info */
6711        for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6712                seq_printf(m, "  PortNumber = %d (of %d)\n",
6713                                p+1,
6714                                ioc->facts.NumberOfPorts);
6715                if (ioc->bus_type == FC) {
6716                        if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6717                                u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6718                                seq_printf(m, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6719                                                a[5], a[4], a[3], a[2], a[1], a[0]);
6720                        }
6721                        seq_printf(m, "    WWN = %08X%08X:%08X%08X\n",
6722                                        ioc->fc_port_page0[p].WWNN.High,
6723                                        ioc->fc_port_page0[p].WWNN.Low,
6724                                        ioc->fc_port_page0[p].WWPN.High,
6725                                        ioc->fc_port_page0[p].WWPN.Low);
6726                }
6727        }
6728
6729        return 0;
6730}
6731
6732static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file)
6733{
6734        return single_open(file, mpt_iocinfo_proc_show, PDE(inode)->data);
6735}
6736
6737static const struct file_operations mpt_iocinfo_proc_fops = {
6738        .owner          = THIS_MODULE,
6739        .open           = mpt_iocinfo_proc_open,
6740        .read           = seq_read,
6741        .llseek         = seq_lseek,
6742        .release        = single_release,
6743};
6744#endif          /* CONFIG_PROC_FS } */
6745
6746/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6747static void
6748mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6749{
6750        buf[0] ='\0';
6751        if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6752                sprintf(buf, " (Exp %02d%02d)",
6753                        (ioc->facts.FWVersion.Word >> 16) & 0x00FF,     /* Month */
6754                        (ioc->facts.FWVersion.Word >> 8) & 0x1F);       /* Day */
6755
6756                /* insider hack! */
6757                if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6758                        strcat(buf, " [MDBG]");
6759        }
6760}
6761
6762/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6763/**
6764 *      mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6765 *      @ioc: Pointer to MPT_ADAPTER structure
6766 *      @buffer: Pointer to buffer where IOC summary info should be written
6767 *      @size: Pointer to number of bytes we wrote (set by this routine)
6768 *      @len: Offset at which to start writing in buffer
6769 *      @showlan: Display LAN stuff?
6770 *
6771 *      This routine writes (english readable) ASCII text, which represents
6772 *      a summary of IOC information, to a buffer.
6773 */
6774void
6775mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6776{
6777        char expVer[32];
6778        int y;
6779
6780        mpt_get_fw_exp_ver(expVer, ioc);
6781
6782        /*
6783         *  Shorter summary of attached ioc's...
6784         */
6785        y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6786                        ioc->name,
6787                        ioc->prod_name,
6788                        MPT_FW_REV_MAGIC_ID_STRING,     /* "FwRev=" or somesuch */
6789                        ioc->facts.FWVersion.Word,
6790                        expVer,
6791                        ioc->facts.NumberOfPorts,
6792                        ioc->req_depth);
6793
6794        if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6795                u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6796                y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6797                        a[5], a[4], a[3], a[2], a[1], a[0]);
6798        }
6799
6800        y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6801
6802        if (!ioc->active)
6803                y += sprintf(buffer+len+y, " (disabled)");
6804
6805        y += sprintf(buffer+len+y, "\n");
6806
6807        *size = y;
6808}
6809
6810static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
6811{
6812        char expVer[32];
6813
6814        mpt_get_fw_exp_ver(expVer, ioc);
6815
6816        /*
6817         *  Shorter summary of attached ioc's...
6818         */
6819        seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6820                        ioc->name,
6821                        ioc->prod_name,
6822                        MPT_FW_REV_MAGIC_ID_STRING,     /* "FwRev=" or somesuch */
6823                        ioc->facts.FWVersion.Word,
6824                        expVer,
6825                        ioc->facts.NumberOfPorts,
6826                        ioc->req_depth);
6827
6828        if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6829                u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6830                seq_printf(m, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6831                        a[5], a[4], a[3], a[2], a[1], a[0]);
6832        }
6833
6834        seq_printf(m, ", IRQ=%d", ioc->pci_irq);
6835
6836        if (!ioc->active)
6837                seq_printf(m, " (disabled)");
6838
6839        seq_putc(m, '\n');
6840}
6841
6842/**
6843 *      mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6844 *      @ioc: Pointer to MPT_ADAPTER structure
6845 *
6846 *      Returns 0 for SUCCESS or -1 if FAILED.
6847 *
6848 *      If -1 is return, then it was not possible to set the flags
6849 **/
6850int
6851mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6852{
6853        unsigned long    flags;
6854        int              retval;
6855
6856        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6857        if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6858            (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6859                retval = -1;
6860                goto out;
6861        }
6862        retval = 0;
6863        ioc->taskmgmt_in_progress = 1;
6864        ioc->taskmgmt_quiesce_io = 1;
6865        if (ioc->alt_ioc) {
6866                ioc->alt_ioc->taskmgmt_in_progress = 1;
6867                ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6868        }
6869 out:
6870        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6871        return retval;
6872}
6873EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6874
6875/**
6876 *      mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6877 *      @ioc: Pointer to MPT_ADAPTER structure
6878 *
6879 **/
6880void
6881mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6882{
6883        unsigned long    flags;
6884
6885        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6886        ioc->taskmgmt_in_progress = 0;
6887        ioc->taskmgmt_quiesce_io = 0;
6888        if (ioc->alt_ioc) {
6889                ioc->alt_ioc->taskmgmt_in_progress = 0;
6890                ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6891        }
6892        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6893}
6894EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6895
6896
6897/**
6898 *      mpt_halt_firmware - Halts the firmware if it is operational and panic
6899 *      the kernel
6900 *      @ioc: Pointer to MPT_ADAPTER structure
6901 *
6902 **/
6903void
6904mpt_halt_firmware(MPT_ADAPTER *ioc)
6905{
6906        u32      ioc_raw_state;
6907
6908        ioc_raw_state = mpt_GetIocState(ioc, 0);
6909
6910        if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6911                printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6912                        ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6913                panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6914                        ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6915        } else {
6916                CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6917                panic("%s: Firmware is halted due to command timeout\n",
6918                        ioc->name);
6919        }
6920}
6921EXPORT_SYMBOL(mpt_halt_firmware);
6922
6923/**
6924 *      mpt_SoftResetHandler - Issues a less expensive reset
6925 *      @ioc: Pointer to MPT_ADAPTER structure
6926 *      @sleepFlag: Indicates if sleep or schedule must be called.
6927 *
6928 *      Returns 0 for SUCCESS or -1 if FAILED.
6929 *
6930 *      Message Unit Reset - instructs the IOC to reset the Reply Post and
6931 *      Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6932 *      All posted buffers are freed, and event notification is turned off.
6933 *      IOC doesn't reply to any outstanding request. This will transfer IOC
6934 *      to READY state.
6935 **/
6936int
6937mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6938{
6939        int              rc;
6940        int              ii;
6941        u8               cb_idx;
6942        unsigned long    flags;
6943        u32              ioc_state;
6944        unsigned long    time_count;
6945
6946        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
6947                ioc->name));
6948
6949        ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6950
6951        if (mpt_fwfault_debug)
6952                mpt_halt_firmware(ioc);
6953
6954        if (ioc_state == MPI_IOC_STATE_FAULT ||
6955            ioc_state == MPI_IOC_STATE_RESET) {
6956                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6957                    "skipping, either in FAULT or RESET state!\n", ioc->name));
6958                return -1;
6959        }
6960
6961        if (ioc->bus_type == FC) {
6962                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6963                    "skipping, because the bus type is FC!\n", ioc->name));
6964                return -1;
6965        }
6966
6967        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6968        if (ioc->ioc_reset_in_progress) {
6969                spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6970                return -1;
6971        }
6972        ioc->ioc_reset_in_progress = 1;
6973        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6974
6975        rc = -1;
6976
6977        for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6978                if (MptResetHandlers[cb_idx])
6979                        mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6980        }
6981
6982        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6983        if (ioc->taskmgmt_in_progress) {
6984                ioc->ioc_reset_in_progress = 0;
6985                spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6986                return -1;
6987        }
6988        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6989        /* Disable reply interrupts (also blocks FreeQ) */
6990        CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
6991        ioc->active = 0;
6992        time_count = jiffies;
6993
6994        rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
6995
6996        for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6997                if (MptResetHandlers[cb_idx])
6998                        mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
6999        }
7000
7001        if (rc)
7002                goto out;
7003
7004        ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7005        if (ioc_state != MPI_IOC_STATE_READY)
7006                goto out;
7007
7008        for (ii = 0; ii < 5; ii++) {
7009                /* Get IOC facts! Allow 5 retries */
7010                rc = GetIocFacts(ioc, sleepFlag,
7011                        MPT_HOSTEVENT_IOC_RECOVER);
7012                if (rc == 0)
7013                        break;
7014                if (sleepFlag == CAN_SLEEP)
7015                        msleep(100);
7016                else
7017                        mdelay(100);
7018        }
7019        if (ii == 5)
7020                goto out;
7021
7022        rc = PrimeIocFifos(ioc);
7023        if (rc != 0)
7024                goto out;
7025
7026        rc = SendIocInit(ioc, sleepFlag);
7027        if (rc != 0)
7028                goto out;
7029
7030        rc = SendEventNotification(ioc, 1, sleepFlag);
7031        if (rc != 0)
7032                goto out;
7033
7034        if (ioc->hard_resets < -1)
7035                ioc->hard_resets++;
7036
7037        /*
7038         * At this point, we know soft reset succeeded.
7039         */
7040
7041        ioc->active = 1;
7042        CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7043
7044 out:
7045        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7046        ioc->ioc_reset_in_progress = 0;
7047        ioc->taskmgmt_quiesce_io = 0;
7048        ioc->taskmgmt_in_progress = 0;
7049        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7050
7051        if (ioc->active) {      /* otherwise, hard reset coming */
7052                for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7053                        if (MptResetHandlers[cb_idx])
7054                                mpt_signal_reset(cb_idx, ioc,
7055                                        MPT_IOC_POST_RESET);
7056                }
7057        }
7058
7059        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7060                "SoftResetHandler: completed (%d seconds): %s\n",
7061                ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7062                ((rc == 0) ? "SUCCESS" : "FAILED")));
7063
7064        return rc;
7065}
7066
7067/**
7068 *      mpt_Soft_Hard_ResetHandler - Try less expensive reset
7069 *      @ioc: Pointer to MPT_ADAPTER structure
7070 *      @sleepFlag: Indicates if sleep or schedule must be called.
7071 *
7072 *      Returns 0 for SUCCESS or -1 if FAILED.
7073 *      Try for softreset first, only if it fails go for expensive
7074 *      HardReset.
7075 **/
7076int
7077mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7078        int ret = -1;
7079
7080        ret = mpt_SoftResetHandler(ioc, sleepFlag);
7081        if (ret == 0)
7082                return ret;
7083        ret = mpt_HardResetHandler(ioc, sleepFlag);
7084        return ret;
7085}
7086EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7087
7088/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7089/*
7090 *      Reset Handling
7091 */
7092/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7093/**
7094 *      mpt_HardResetHandler - Generic reset handler
7095 *      @ioc: Pointer to MPT_ADAPTER structure
7096 *      @sleepFlag: Indicates if sleep or schedule must be called.
7097 *
7098 *      Issues SCSI Task Management call based on input arg values.
7099 *      If TaskMgmt fails, returns associated SCSI request.
7100 *
7101 *      Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7102 *      or a non-interrupt thread.  In the former, must not call schedule().
7103 *
7104 *      Note: A return of -1 is a FATAL error case, as it means a
7105 *      FW reload/initialization failed.
7106 *
7107 *      Returns 0 for SUCCESS or -1 if FAILED.
7108 */
7109int
7110mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7111{
7112        int      rc;
7113        u8       cb_idx;
7114        unsigned long    flags;
7115        unsigned long    time_count;
7116
7117        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7118#ifdef MFCNT
7119        printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7120        printk("MF count 0x%x !\n", ioc->mfcnt);
7121#endif
7122        if (mpt_fwfault_debug)
7123                mpt_halt_firmware(ioc);
7124
7125        /* Reset the adapter. Prevent more than 1 call to
7126         * mpt_do_ioc_recovery at any instant in time.
7127         */
7128        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7129        if (ioc->ioc_reset_in_progress) {
7130                spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7131                return 0;
7132        }
7133        ioc->ioc_reset_in_progress = 1;
7134        if (ioc->alt_ioc)
7135                ioc->alt_ioc->ioc_reset_in_progress = 1;
7136        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7137
7138
7139        /* The SCSI driver needs to adjust timeouts on all current
7140         * commands prior to the diagnostic reset being issued.
7141         * Prevents timeouts occurring during a diagnostic reset...very bad.
7142         * For all other protocol drivers, this is a no-op.
7143         */
7144        for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7145                if (MptResetHandlers[cb_idx]) {
7146                        mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7147                        if (ioc->alt_ioc)
7148                                mpt_signal_reset(cb_idx, ioc->alt_ioc,
7149                                        MPT_IOC_SETUP_RESET);
7150                }
7151        }
7152
7153        time_count = jiffies;
7154        rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7155        if (rc != 0) {
7156                printk(KERN_WARNING MYNAM
7157                       ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7158                       rc, ioc->name, mpt_GetIocState(ioc, 0));
7159        } else {
7160                if (ioc->hard_resets < -1)
7161                        ioc->hard_resets++;
7162        }
7163
7164        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7165        ioc->ioc_reset_in_progress = 0;
7166        ioc->taskmgmt_quiesce_io = 0;
7167        ioc->taskmgmt_in_progress = 0;
7168        if (ioc->alt_ioc) {
7169                ioc->alt_ioc->ioc_reset_in_progress = 0;
7170                ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7171                ioc->alt_ioc->taskmgmt_in_progress = 0;
7172        }
7173        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7174
7175        for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7176                if (MptResetHandlers[cb_idx]) {
7177                        mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7178                        if (ioc->alt_ioc)
7179                                mpt_signal_reset(cb_idx,
7180                                        ioc->alt_ioc, MPT_IOC_POST_RESET);
7181                }
7182        }
7183
7184        dtmprintk(ioc,
7185            printk(MYIOC_s_DEBUG_FMT
7186                "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7187                jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7188                "SUCCESS" : "FAILED")));
7189
7190        return rc;
7191}
7192
7193#ifdef CONFIG_FUSION_LOGGING
7194static void
7195mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7196{
7197        char *ds = NULL;
7198        u32 evData0;
7199        int ii;
7200        u8 event;
7201        char *evStr = ioc->evStr;
7202
7203        event = le32_to_cpu(pEventReply->Event) & 0xFF;
7204        evData0 = le32_to_cpu(pEventReply->Data[0]);
7205
7206        switch(event) {
7207        case MPI_EVENT_NONE:
7208                ds = "None";
7209                break;
7210        case MPI_EVENT_LOG_DATA:
7211                ds = "Log Data";
7212                break;
7213        case MPI_EVENT_STATE_CHANGE:
7214                ds = "State Change";
7215                break;
7216        case MPI_EVENT_UNIT_ATTENTION:
7217                ds = "Unit Attention";
7218                break;
7219        case MPI_EVENT_IOC_BUS_RESET:
7220                ds = "IOC Bus Reset";
7221                break;
7222        case MPI_EVENT_EXT_BUS_RESET:
7223                ds = "External Bus Reset";
7224                break;
7225        case MPI_EVENT_RESCAN:
7226                ds = "Bus Rescan Event";
7227                break;
7228        case MPI_EVENT_LINK_STATUS_CHANGE:
7229                if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7230                        ds = "Link Status(FAILURE) Change";
7231                else
7232                        ds = "Link Status(ACTIVE) Change";
7233                break;
7234        case MPI_EVENT_LOOP_STATE_CHANGE:
7235                if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7236                        ds = "Loop State(LIP) Change";
7237                else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7238                        ds = "Loop State(LPE) Change";
7239                else
7240                        ds = "Loop State(LPB) Change";
7241                break;
7242        case MPI_EVENT_LOGOUT:
7243                ds = "Logout";
7244                break;
7245        case MPI_EVENT_EVENT_CHANGE:
7246                if (evData0)
7247                        ds = "Events ON";
7248                else
7249                        ds = "Events OFF";
7250                break;
7251        case MPI_EVENT_INTEGRATED_RAID:
7252        {
7253                u8 ReasonCode = (u8)(evData0 >> 16);
7254                switch (ReasonCode) {
7255                case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7256                        ds = "Integrated Raid: Volume Created";
7257                        break;
7258                case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7259                        ds = "Integrated Raid: Volume Deleted";
7260                        break;
7261                case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7262                        ds = "Integrated Raid: Volume Settings Changed";
7263                        break;
7264                case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7265                        ds = "Integrated Raid: Volume Status Changed";
7266                        break;
7267                case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7268                        ds = "Integrated Raid: Volume Physdisk Changed";
7269                        break;
7270                case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7271                        ds = "Integrated Raid: Physdisk Created";
7272                        break;
7273                case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7274                        ds = "Integrated Raid: Physdisk Deleted";
7275                        break;
7276                case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7277                        ds = "Integrated Raid: Physdisk Settings Changed";
7278                        break;
7279                case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7280                        ds = "Integrated Raid: Physdisk Status Changed";
7281                        break;
7282                case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7283                        ds = "Integrated Raid: Domain Validation Needed";
7284                        break;
7285                case MPI_EVENT_RAID_RC_SMART_DATA :
7286                        ds = "Integrated Raid; Smart Data";
7287                        break;
7288                case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7289                        ds = "Integrated Raid: Replace Action Started";
7290                        break;
7291                default:
7292                        ds = "Integrated Raid";
7293                break;
7294                }
7295                break;
7296        }
7297        case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7298                ds = "SCSI Device Status Change";
7299                break;
7300        case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7301        {
7302                u8 id = (u8)(evData0);
7303                u8 channel = (u8)(evData0 >> 8);
7304                u8 ReasonCode = (u8)(evData0 >> 16);
7305                switch (ReasonCode) {
7306                case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7307                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7308                            "SAS Device Status Change: Added: "
7309                            "id=%d channel=%d", id, channel);
7310                        break;
7311                case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7312                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7313                            "SAS Device Status Change: Deleted: "
7314                            "id=%d channel=%d", id, channel);
7315                        break;
7316                case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7317                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7318                            "SAS Device Status Change: SMART Data: "
7319                            "id=%d channel=%d", id, channel);
7320                        break;
7321                case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7322                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7323                            "SAS Device Status Change: No Persistancy: "
7324                            "id=%d channel=%d", id, channel);
7325                        break;
7326                case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7327                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7328                            "SAS Device Status Change: Unsupported Device "
7329                            "Discovered : id=%d channel=%d", id, channel);
7330                        break;
7331                case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7332                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7333                            "SAS Device Status Change: Internal Device "
7334                            "Reset : id=%d channel=%d", id, channel);
7335                        break;
7336                case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7337                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7338                            "SAS Device Status Change: Internal Task "
7339                            "Abort : id=%d channel=%d", id, channel);
7340                        break;
7341                case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7342                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7343                            "SAS Device Status Change: Internal Abort "
7344                            "Task Set : id=%d channel=%d", id, channel);
7345                        break;
7346                case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7347                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7348                            "SAS Device Status Change: Internal Clear "
7349                            "Task Set : id=%d channel=%d", id, channel);
7350                        break;
7351                case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7352                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7353                            "SAS Device Status Change: Internal Query "
7354                            "Task : id=%d channel=%d", id, channel);
7355                        break;
7356                default:
7357                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7358                            "SAS Device Status Change: Unknown: "
7359                            "id=%d channel=%d", id, channel);
7360                        break;
7361                }
7362                break;
7363        }
7364        case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7365                ds = "Bus Timer Expired";
7366                break;
7367        case MPI_EVENT_QUEUE_FULL:
7368        {
7369                u16 curr_depth = (u16)(evData0 >> 16);
7370                u8 channel = (u8)(evData0 >> 8);
7371                u8 id = (u8)(evData0);
7372
7373                snprintf(evStr, EVENT_DESCR_STR_SZ,
7374                   "Queue Full: channel=%d id=%d depth=%d",
7375                   channel, id, curr_depth);
7376                break;
7377        }
7378        case MPI_EVENT_SAS_SES:
7379                ds = "SAS SES Event";
7380                break;
7381        case MPI_EVENT_PERSISTENT_TABLE_FULL:
7382                ds = "Persistent Table Full";
7383                break;
7384        case MPI_EVENT_SAS_PHY_LINK_STATUS:
7385        {
7386                u8 LinkRates = (u8)(evData0 >> 8);
7387                u8 PhyNumber = (u8)(evData0);
7388                LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7389                        MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7390                switch (LinkRates) {
7391                case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7392                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7393                           "SAS PHY Link Status: Phy=%d:"
7394                           " Rate Unknown",PhyNumber);
7395                        break;
7396                case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7397                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7398                           "SAS PHY Link Status: Phy=%d:"
7399                           " Phy Disabled",PhyNumber);
7400                        break;
7401                case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7402                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7403                           "SAS PHY Link Status: Phy=%d:"
7404                           " Failed Speed Nego",PhyNumber);
7405                        break;
7406                case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7407                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7408                           "SAS PHY Link Status: Phy=%d:"
7409                           " Sata OOB Completed",PhyNumber);
7410                        break;
7411                case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7412                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7413                           "SAS PHY Link Status: Phy=%d:"
7414                           " Rate 1.5 Gbps",PhyNumber);
7415                        break;
7416                case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7417                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7418                           "SAS PHY Link Status: Phy=%d:"
7419                           " Rate 3.0 Gbps", PhyNumber);
7420                        break;
7421                case MPI_EVENT_SAS_PLS_LR_RATE_6_0:
7422                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7423                           "SAS PHY Link Status: Phy=%d:"
7424                           " Rate 6.0 Gbps", PhyNumber);
7425                        break;
7426                default:
7427                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7428                           "SAS PHY Link Status: Phy=%d", PhyNumber);
7429                        break;
7430                }
7431                break;
7432        }
7433        case MPI_EVENT_SAS_DISCOVERY_ERROR:
7434                ds = "SAS Discovery Error";
7435                break;
7436        case MPI_EVENT_IR_RESYNC_UPDATE:
7437        {
7438                u8 resync_complete = (u8)(evData0 >> 16);
7439                snprintf(evStr, EVENT_DESCR_STR_SZ,
7440                    "IR Resync Update: Complete = %d:",resync_complete);
7441                break;
7442        }
7443        case MPI_EVENT_IR2:
7444        {
7445                u8 id = (u8)(evData0);
7446                u8 channel = (u8)(evData0 >> 8);
7447                u8 phys_num = (u8)(evData0 >> 24);
7448                u8 ReasonCode = (u8)(evData0 >> 16);
7449
7450                switch (ReasonCode) {
7451                case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7452                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7453                            "IR2: LD State Changed: "
7454                            "id=%d channel=%d phys_num=%d",
7455                            id, channel, phys_num);
7456                        break;
7457                case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7458                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7459                            "IR2: PD State Changed "
7460                            "id=%d channel=%d phys_num=%d",
7461                            id, channel, phys_num);
7462                        break;
7463                case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7464                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7465                            "IR2: Bad Block Table Full: "
7466                            "id=%d channel=%d phys_num=%d",
7467                            id, channel, phys_num);
7468                        break;
7469                case MPI_EVENT_IR2_RC_PD_INSERTED:
7470                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7471                            "IR2: PD Inserted: "
7472                            "id=%d channel=%d phys_num=%d",
7473                            id, channel, phys_num);
7474                        break;
7475                case MPI_EVENT_IR2_RC_PD_REMOVED:
7476                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7477                            "IR2: PD Removed: "
7478                            "id=%d channel=%d phys_num=%d",
7479                            id, channel, phys_num);
7480                        break;
7481                case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7482                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7483                            "IR2: Foreign CFG Detected: "
7484                            "id=%d channel=%d phys_num=%d",
7485                            id, channel, phys_num);
7486                        break;
7487                case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7488                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7489                            "IR2: Rebuild Medium Error: "
7490                            "id=%d channel=%d phys_num=%d",
7491                            id, channel, phys_num);
7492                        break;
7493                case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7494                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7495                            "IR2: Dual Port Added: "
7496                            "id=%d channel=%d phys_num=%d",
7497                            id, channel, phys_num);
7498                        break;
7499                case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7500                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7501                            "IR2: Dual Port Removed: "
7502                            "id=%d channel=%d phys_num=%d",
7503                            id, channel, phys_num);
7504                        break;
7505                default:
7506                        ds = "IR2";
7507                break;
7508                }
7509                break;
7510        }
7511        case MPI_EVENT_SAS_DISCOVERY:
7512        {
7513                if (evData0)
7514                        ds = "SAS Discovery: Start";
7515                else
7516                        ds = "SAS Discovery: Stop";
7517                break;
7518        }
7519        case MPI_EVENT_LOG_ENTRY_ADDED:
7520                ds = "SAS Log Entry Added";
7521                break;
7522
7523        case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7524        {
7525                u8 phy_num = (u8)(evData0);
7526                u8 port_num = (u8)(evData0 >> 8);
7527                u8 port_width = (u8)(evData0 >> 16);
7528                u8 primative = (u8)(evData0 >> 24);
7529                snprintf(evStr, EVENT_DESCR_STR_SZ,
7530                    "SAS Broadcase Primative: phy=%d port=%d "
7531                    "width=%d primative=0x%02x",
7532                    phy_num, port_num, port_width, primative);
7533                break;
7534        }
7535
7536        case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7537        {
7538                u8 reason = (u8)(evData0);
7539
7540                switch (reason) {
7541                case MPI_EVENT_SAS_INIT_RC_ADDED:
7542                        ds = "SAS Initiator Status Change: Added";
7543                        break;
7544                case MPI_EVENT_SAS_INIT_RC_REMOVED:
7545                        ds = "SAS Initiator Status Change: Deleted";
7546                        break;
7547                default:
7548                        ds = "SAS Initiator Status Change";
7549                        break;
7550                }
7551                break;
7552        }
7553
7554        case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7555        {
7556                u8 max_init = (u8)(evData0);
7557                u8 current_init = (u8)(evData0 >> 8);
7558
7559                snprintf(evStr, EVENT_DESCR_STR_SZ,
7560                    "SAS Initiator Device Table Overflow: max initiators=%02d "
7561                    "current initators=%02d",
7562                    max_init, current_init);
7563                break;
7564        }
7565        case MPI_EVENT_SAS_SMP_ERROR:
7566        {
7567                u8 status = (u8)(evData0);
7568                u8 port_num = (u8)(evData0 >> 8);
7569                u8 result = (u8)(evData0 >> 16);
7570
7571                if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7572                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7573                            "SAS SMP Error: port=%d result=0x%02x",
7574                            port_num, result);
7575                else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7576                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7577                            "SAS SMP Error: port=%d : CRC Error",
7578                            port_num);
7579                else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7580                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7581                            "SAS SMP Error: port=%d : Timeout",
7582                            port_num);
7583                else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7584                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7585                            "SAS SMP Error: port=%d : No Destination",
7586                            port_num);
7587                else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7588                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7589                            "SAS SMP Error: port=%d : Bad Destination",
7590                            port_num);
7591                else
7592                        snprintf(evStr, EVENT_DESCR_STR_SZ,
7593                            "SAS SMP Error: port=%d : status=0x%02x",
7594                            port_num, status);
7595                break;
7596        }
7597
7598        case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7599        {
7600                u8 reason = (u8)(evData0);
7601
7602                switch (reason) {
7603                case MPI_EVENT_SAS_EXP_RC_ADDED:
7604                        ds = "Expander Status Change: Added";
7605                        break;
7606                case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7607                        ds = "Expander Status Change: Deleted";
7608                        break;
7609                default:
7610                        ds = "Expander Status Change";
7611                        break;
7612                }
7613                break;
7614        }
7615
7616        /*
7617         *  MPT base "custom" events may be added here...
7618         */
7619        default:
7620                ds = "Unknown";
7621                break;
7622        }
7623        if (ds)
7624                strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7625
7626
7627        devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7628            "MPT event:(%02Xh) : %s\n",
7629            ioc->name, event, evStr));
7630
7631        devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7632            ": Event data:\n"));
7633        for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7634                devtverboseprintk(ioc, printk(" %08x",
7635                    le32_to_cpu(pEventReply->Data[ii])));
7636        devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7637}
7638#endif
7639/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7640/**
7641 *      ProcessEventNotification - Route EventNotificationReply to all event handlers
7642 *      @ioc: Pointer to MPT_ADAPTER structure
7643 *      @pEventReply: Pointer to EventNotification reply frame
7644 *      @evHandlers: Pointer to integer, number of event handlers
7645 *
7646 *      Routes a received EventNotificationReply to all currently registered
7647 *      event handlers.
7648 *      Returns sum of event handlers return values.
7649 */
7650static int
7651ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7652{
7653        u16 evDataLen;
7654        u32 evData0 = 0;
7655        int ii;
7656        u8 cb_idx;
7657        int r = 0;
7658        int handlers = 0;
7659        u8 event;
7660
7661        /*
7662         *  Do platform normalization of values
7663         */
7664        event = le32_to_cpu(pEventReply->Event) & 0xFF;
7665        evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7666        if (evDataLen) {
7667                evData0 = le32_to_cpu(pEventReply->Data[0]);
7668        }
7669
7670#ifdef CONFIG_FUSION_LOGGING
7671        if (evDataLen)
7672                mpt_display_event_info(ioc, pEventReply);
7673#endif
7674
7675        /*
7676         *  Do general / base driver event processing
7677         */
7678        switch(event) {
7679        case MPI_EVENT_EVENT_CHANGE:            /* 0A */
7680                if (evDataLen) {
7681                        u8 evState = evData0 & 0xFF;
7682
7683                        /* CHECKME! What if evState unexpectedly says OFF (0)? */
7684
7685                        /* Update EventState field in cached IocFacts */
7686                        if (ioc->facts.Function) {
7687                                ioc->facts.EventState = evState;
7688                        }
7689                }
7690                break;
7691        case MPI_EVENT_INTEGRATED_RAID:
7692                mptbase_raid_process_event_data(ioc,
7693                    (MpiEventDataRaid_t *)pEventReply->Data);
7694                break;
7695        default:
7696                break;
7697        }
7698
7699        /*
7700         * Should this event be logged? Events are written sequentially.
7701         * When buffer is full, start again at the top.
7702         */
7703        if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7704                int idx;
7705
7706                idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7707
7708                ioc->events[idx].event = event;
7709                ioc->events[idx].eventContext = ioc->eventContext;
7710
7711                for (ii = 0; ii < 2; ii++) {
7712                        if (ii < evDataLen)
7713                                ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7714                        else
7715                                ioc->events[idx].data[ii] =  0;
7716                }
7717
7718                ioc->eventContext++;
7719        }
7720
7721
7722        /*
7723         *  Call each currently registered protocol event handler.
7724         */
7725        for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7726                if (MptEvHandlers[cb_idx]) {
7727                        devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7728                            "Routing Event to event handler #%d\n",
7729                            ioc->name, cb_idx));
7730                        r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7731                        handlers++;
7732                }
7733        }
7734        /* FIXME?  Examine results here? */
7735
7736        /*
7737         *  If needed, send (a single) EventAck.
7738         */
7739        if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7740                devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7741                        "EventAck required\n",ioc->name));
7742                if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7743                        devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7744                                        ioc->name, ii));
7745                }
7746        }
7747
7748        *evHandlers = handlers;
7749        return r;
7750}
7751
7752/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7753/**
7754 *      mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7755 *      @ioc: Pointer to MPT_ADAPTER structure
7756 *      @log_info: U32 LogInfo reply word from the IOC
7757 *
7758 *      Refer to lsi/mpi_log_fc.h.
7759 */
7760static void
7761mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7762{
7763        char *desc = "unknown";
7764
7765        switch (log_info & 0xFF000000) {
7766        case MPI_IOCLOGINFO_FC_INIT_BASE:
7767                desc = "FCP Initiator";
7768                break;
7769        case MPI_IOCLOGINFO_FC_TARGET_BASE:
7770                desc = "FCP Target";
7771                break;
7772        case MPI_IOCLOGINFO_FC_LAN_BASE:
7773                desc = "LAN";
7774                break;
7775        case MPI_IOCLOGINFO_FC_MSG_BASE:
7776                desc = "MPI Message Layer";
7777                break;
7778        case MPI_IOCLOGINFO_FC_LINK_BASE:
7779                desc = "FC Link";
7780                break;
7781        case MPI_IOCLOGINFO_FC_CTX_BASE:
7782                desc = "Context Manager";
7783                break;
7784        case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7785                desc = "Invalid Field Offset";
7786                break;
7787        case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7788                desc = "State Change Info";
7789                break;
7790        }
7791
7792        printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7793                        ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7794}
7795
7796/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7797/**
7798 *      mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7799 *      @ioc: Pointer to MPT_ADAPTER structure
7800 *      @log_info: U32 LogInfo word from the IOC
7801 *
7802 *      Refer to lsi/sp_log.h.
7803 */
7804static void
7805mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7806{
7807        u32 info = log_info & 0x00FF0000;
7808        char *desc = "unknown";
7809
7810        switch (info) {
7811        case 0x00010000:
7812                desc = "bug! MID not found";
7813                break;
7814
7815        case 0x00020000:
7816                desc = "Parity Error";
7817                break;
7818
7819        case 0x00030000:
7820                desc = "ASYNC Outbound Overrun";
7821                break;
7822
7823        case 0x00040000:
7824                desc = "SYNC Offset Error";
7825                break;
7826
7827        case 0x00050000:
7828                desc = "BM Change";
7829                break;
7830
7831        case 0x00060000:
7832                desc = "Msg In Overflow";
7833                break;
7834
7835        case 0x00070000:
7836                desc = "DMA Error";
7837                break;
7838
7839        case 0x00080000:
7840                desc = "Outbound DMA Overrun";
7841                break;
7842
7843        case 0x00090000:
7844                desc = "Task Management";
7845                break;
7846
7847        case 0x000A0000:
7848                desc = "Device Problem";
7849                break;
7850
7851        case 0x000B0000:
7852                desc = "Invalid Phase Change";
7853                break;
7854
7855        case 0x000C0000:
7856                desc = "Untagged Table Size";
7857                break;
7858
7859        }
7860
7861        printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7862}
7863
7864/* strings for sas loginfo */
7865        static char *originator_str[] = {
7866                "IOP",                                          /* 00h */
7867                "PL",                                           /* 01h */
7868                "IR"                                            /* 02h */
7869        };
7870        static char *iop_code_str[] = {
7871                NULL,                                           /* 00h */
7872                "Invalid SAS Address",                          /* 01h */
7873                NULL,                                           /* 02h */
7874                "Invalid Page",                                 /* 03h */
7875                "Diag Message Error",                           /* 04h */
7876                "Task Terminated",                              /* 05h */
7877                "Enclosure Management",                         /* 06h */
7878                "Target Mode"                                   /* 07h */
7879        };
7880        static char *pl_code_str[] = {
7881                NULL,                                           /* 00h */
7882                "Open Failure",                                 /* 01h */
7883                "Invalid Scatter Gather List",                  /* 02h */
7884                "Wrong Relative Offset or Frame Length",        /* 03h */
7885                "Frame Transfer Error",                         /* 04h */
7886                "Transmit Frame Connected Low",                 /* 05h */
7887                "SATA Non-NCQ RW Error Bit Set",                /* 06h */
7888                "SATA Read Log Receive Data Error",             /* 07h */
7889                "SATA NCQ Fail All Commands After Error",       /* 08h */
7890                "SATA Error in Receive Set Device Bit FIS",     /* 09h */
7891                "Receive Frame Invalid Message",                /* 0Ah */
7892                "Receive Context Message Valid Error",          /* 0Bh */
7893                "Receive Frame Current Frame Error",            /* 0Ch */
7894                "SATA Link Down",                               /* 0Dh */
7895                "Discovery SATA Init W IOS",                    /* 0Eh */
7896                "Config Invalid Page",                          /* 0Fh */
7897                "Discovery SATA Init Timeout",                  /* 10h */
7898                "Reset",                                        /* 11h */
7899                "Abort",                                        /* 12h */
7900                "IO Not Yet Executed",                          /* 13h */
7901                "IO Executed",                                  /* 14h */
7902                "Persistent Reservation Out Not Affiliation "
7903                    "Owner",                                    /* 15h */
7904                "Open Transmit DMA Abort",                      /* 16h */
7905                "IO Device Missing Delay Retry",                /* 17h */
7906                "IO Cancelled Due to Receive Error",            /* 18h */
7907                NULL,                                           /* 19h */
7908                NULL,                                           /* 1Ah */
7909                NULL,                                           /* 1Bh */
7910                NULL,                                           /* 1Ch */
7911                NULL,                                           /* 1Dh */
7912                NULL,                                           /* 1Eh */
7913                NULL,                                           /* 1Fh */
7914                "Enclosure Management"                          /* 20h */
7915        };
7916        static char *ir_code_str[] = {
7917                "Raid Action Error",                            /* 00h */
7918                NULL,                                           /* 00h */
7919                NULL,                                           /* 01h */
7920                NULL,                                           /* 02h */
7921                NULL,                                           /* 03h */
7922                NULL,                                           /* 04h */
7923                NULL,                                           /* 05h */
7924                NULL,                                           /* 06h */
7925                NULL                                            /* 07h */
7926        };
7927        static char *raid_sub_code_str[] = {
7928                NULL,                                           /* 00h */
7929                "Volume Creation Failed: Data Passed too "
7930                    "Large",                                    /* 01h */
7931                "Volume Creation Failed: Duplicate Volumes "
7932                    "Attempted",                                /* 02h */
7933                "Volume Creation Failed: Max Number "
7934                    "Supported Volumes Exceeded",               /* 03h */
7935                "Volume Creation Failed: DMA Error",            /* 04h */
7936                "Volume Creation Failed: Invalid Volume Type",  /* 05h */
7937                "Volume Creation Failed: Error Reading "
7938                    "MFG Page 4",                               /* 06h */
7939                "Volume Creation Failed: Creating Internal "
7940                    "Structures",                               /* 07h */
7941                NULL,                                           /* 08h */
7942                NULL,                                           /* 09h */
7943                NULL,                                           /* 0Ah */
7944                NULL,                                           /* 0Bh */
7945                NULL,                                           /* 0Ch */
7946                NULL,                                           /* 0Dh */
7947                NULL,                                           /* 0Eh */
7948                NULL,                                           /* 0Fh */
7949                "Activation failed: Already Active Volume",     /* 10h */
7950                "Activation failed: Unsupported Volume Type",   /* 11h */
7951                "Activation failed: Too Many Active Volumes",   /* 12h */
7952                "Activation failed: Volume ID in Use",          /* 13h */
7953                "Activation failed: Reported Failure",          /* 14h */
7954                "Activation failed: Importing a Volume",        /* 15h */
7955                NULL,                                           /* 16h */
7956                NULL,                                           /* 17h */
7957                NULL,                                           /* 18h */
7958                NULL,                                           /* 19h */
7959                NULL,                                           /* 1Ah */
7960                NULL,                                           /* 1Bh */
7961                NULL,                                           /* 1Ch */
7962                NULL,                                           /* 1Dh */
7963                NULL,                                           /* 1Eh */
7964                NULL,                                           /* 1Fh */
7965                "Phys Disk failed: Too Many Phys Disks",        /* 20h */
7966                "Phys Disk failed: Data Passed too Large",      /* 21h */
7967                "Phys Disk failed: DMA Error",                  /* 22h */
7968                "Phys Disk failed: Invalid <channel:id>",       /* 23h */
7969                "Phys Disk failed: Creating Phys Disk Config "
7970                    "Page",                                     /* 24h */
7971                NULL,                                           /* 25h */
7972                NULL,                                           /* 26h */
7973                NULL,                                           /* 27h */
7974                NULL,                                           /* 28h */
7975                NULL,                                           /* 29h */
7976                NULL,                                           /* 2Ah */
7977                NULL,                                           /* 2Bh */
7978                NULL,                                           /* 2Ch */
7979                NULL,                                           /* 2Dh */
7980                NULL,                                           /* 2Eh */
7981                NULL,                                           /* 2Fh */
7982                "Compatibility Error: IR Disabled",             /* 30h */
7983                "Compatibility Error: Inquiry Command Failed",  /* 31h */
7984                "Compatibility Error: Device not Direct Access "
7985                    "Device ",                                  /* 32h */
7986                "Compatibility Error: Removable Device Found",  /* 33h */
7987                "Compatibility Error: Device SCSI Version not "
7988                    "2 or Higher",                              /* 34h */
7989                "Compatibility Error: SATA Device, 48 BIT LBA "
7990                    "not Supported",                            /* 35h */
7991                "Compatibility Error: Device doesn't have "
7992                    "512 Byte Block Sizes",                     /* 36h */
7993                "Compatibility Error: Volume Type Check Failed", /* 37h */
7994                "Compatibility Error: Volume Type is "
7995                    "Unsupported by FW",                        /* 38h */
7996                "Compatibility Error: Disk Drive too Small for "
7997                    "use in Volume",                            /* 39h */
7998                "Compatibility Error: Phys Disk for Create "
7999                    "Volume not Found",                         /* 3Ah */
8000                "Compatibility Error: Too Many or too Few "
8001                    "Disks for Volume Type",                    /* 3Bh */
8002                "Compatibility Error: Disk stripe Sizes "
8003                    "Must be 64KB",                             /* 3Ch */
8004                "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8005        };
8006
8007/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8008/**
8009 *      mpt_sas_log_info - Log information returned from SAS IOC.
8010 *      @ioc: Pointer to MPT_ADAPTER structure
8011 *      @log_info: U32 LogInfo reply word from the IOC
8012 *      @cb_idx: callback function's handle
8013 *
8014 *      Refer to lsi/mpi_log_sas.h.
8015 **/
8016static void
8017mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
8018{
8019union loginfo_type {
8020        u32     loginfo;
8021        struct {
8022                u32     subcode:16;
8023                u32     code:8;
8024                u32     originator:4;
8025                u32     bus_type:4;
8026        }dw;
8027};
8028        union loginfo_type sas_loginfo;
8029        char *originator_desc = NULL;
8030        char *code_desc = NULL;
8031        char *sub_code_desc = NULL;
8032
8033        sas_loginfo.loginfo = log_info;
8034        if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8035            (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8036                return;
8037
8038        originator_desc = originator_str[sas_loginfo.dw.originator];
8039
8040        switch (sas_loginfo.dw.originator) {
8041
8042                case 0:  /* IOP */
8043                        if (sas_loginfo.dw.code <
8044                            ARRAY_SIZE(iop_code_str))
8045                                code_desc = iop_code_str[sas_loginfo.dw.code];
8046                        break;
8047                case 1:  /* PL */
8048                        if (sas_loginfo.dw.code <
8049                            ARRAY_SIZE(pl_code_str))
8050                                code_desc = pl_code_str[sas_loginfo.dw.code];
8051                        break;
8052                case 2:  /* IR */
8053                        if (sas_loginfo.dw.code >=
8054                            ARRAY_SIZE(ir_code_str))
8055                                break;
8056                        code_desc = ir_code_str[sas_loginfo.dw.code];
8057                        if (sas_loginfo.dw.subcode >=
8058                            ARRAY_SIZE(raid_sub_code_str))
8059                                break;
8060                        if (sas_loginfo.dw.code == 0)
8061                                sub_code_desc =
8062                                    raid_sub_code_str[sas_loginfo.dw.subcode];
8063                        break;
8064                default:
8065                        return;
8066        }
8067
8068        if (sub_code_desc != NULL)
8069                printk(MYIOC_s_INFO_FMT
8070                        "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8071                        " SubCode={%s} cb_idx %s\n",
8072                        ioc->name, log_info, originator_desc, code_desc,
8073                        sub_code_desc, MptCallbacksName[cb_idx]);
8074        else if (code_desc != NULL)
8075                printk(MYIOC_s_INFO_FMT
8076                        "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8077                        " SubCode(0x%04x) cb_idx %s\n",
8078                        ioc->name, log_info, originator_desc, code_desc,
8079                        sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]);
8080        else
8081                printk(MYIOC_s_INFO_FMT
8082                        "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8083                        " SubCode(0x%04x) cb_idx %s\n",
8084                        ioc->name, log_info, originator_desc,
8085                        sas_loginfo.dw.code, sas_loginfo.dw.subcode,
8086                        MptCallbacksName[cb_idx]);
8087}
8088
8089/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8090/**
8091 *      mpt_iocstatus_info_config - IOCSTATUS information for config pages
8092 *      @ioc: Pointer to MPT_ADAPTER structure
8093 *      @ioc_status: U32 IOCStatus word from IOC
8094 *      @mf: Pointer to MPT request frame
8095 *
8096 *      Refer to lsi/mpi.h.
8097 **/
8098static void
8099mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8100{
8101        Config_t *pReq = (Config_t *)mf;
8102        char extend_desc[EVENT_DESCR_STR_SZ];
8103        char *desc = NULL;
8104        u32 form;
8105        u8 page_type;
8106
8107        if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8108                page_type = pReq->ExtPageType;
8109        else
8110                page_type = pReq->Header.PageType;
8111
8112        /*
8113         * ignore invalid page messages for GET_NEXT_HANDLE
8114         */
8115        form = le32_to_cpu(pReq->PageAddress);
8116        if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8117                if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8118                    page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8119                    page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8120                        if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8121                                MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8122                                return;
8123                }
8124                if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8125                        if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8126                                MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8127                                return;
8128        }
8129
8130        snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8131            "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8132            page_type, pReq->Header.PageNumber, pReq->Action, form);
8133
8134        switch (ioc_status) {
8135
8136        case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8137                desc = "Config Page Invalid Action";
8138                break;
8139
8140        case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
8141                desc = "Config Page Invalid Type";
8142                break;
8143
8144        case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
8145                desc = "Config Page Invalid Page";
8146                break;
8147
8148        case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
8149                desc = "Config Page Invalid Data";
8150                break;
8151
8152        case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
8153                desc = "Config Page No Defaults";
8154                break;
8155
8156        case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
8157                desc = "Config Page Can't Commit";
8158                break;
8159        }
8160
8161        if (!desc)
8162                return;
8163
8164        dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8165            ioc->name, ioc_status, desc, extend_desc));
8166}
8167
8168/**
8169 *      mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8170 *      @ioc: Pointer to MPT_ADAPTER structure
8171 *      @ioc_status: U32 IOCStatus word from IOC
8172 *      @mf: Pointer to MPT request frame
8173 *
8174 *      Refer to lsi/mpi.h.
8175 **/
8176static void
8177mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8178{
8179        u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8180        char *desc = NULL;
8181
8182        switch (status) {
8183
8184/****************************************************************************/
8185/*  Common IOCStatus values for all replies                                 */
8186/****************************************************************************/
8187
8188        case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8189                desc = "Invalid Function";
8190                break;
8191
8192        case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8193                desc = "Busy";
8194                break;
8195
8196        case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8197                desc = "Invalid SGL";
8198                break;
8199
8200        case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8201                desc = "Internal Error";
8202                break;
8203
8204        case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8205                desc = "Reserved";
8206                break;
8207
8208        case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8209                desc = "Insufficient Resources";
8210                break;
8211
8212        case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8213                desc = "Invalid Field";
8214                break;
8215
8216        case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8217                desc = "Invalid State";
8218                break;
8219
8220/****************************************************************************/
8221/*  Config IOCStatus values                                                 */
8222/****************************************************************************/
8223
8224        case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8225        case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
8226        case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
8227        case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
8228        case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
8229        case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
8230                mpt_iocstatus_info_config(ioc, status, mf);
8231                break;
8232
8233/****************************************************************************/
8234/*  SCSIIO Reply (SPI, FCP, SAS) initiator values                           */
8235/*                                                                          */
8236/*  Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8237/*                                                                          */
8238/****************************************************************************/
8239
8240        case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8241        case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8242        case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8243        case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8244        case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8245        case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8246        case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8247        case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8248        case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8249        case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8250        case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8251        case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8252        case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8253                break;
8254
8255/****************************************************************************/
8256/*  SCSI Target values                                                      */
8257/****************************************************************************/
8258
8259        case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8260                desc = "Target: Priority IO";
8261                break;
8262
8263        case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8264                desc = "Target: Invalid Port";
8265                break;
8266
8267        case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8268                desc = "Target Invalid IO Index:";
8269                break;
8270
8271        case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8272                desc = "Target: Aborted";
8273                break;
8274
8275        case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8276                desc = "Target: No Conn Retryable";
8277                break;
8278
8279        case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8280                desc = "Target: No Connection";
8281                break;
8282
8283        case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8284                desc = "Target: Transfer Count Mismatch";
8285                break;
8286
8287        case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8288                desc = "Target: STS Data not Sent";
8289                break;
8290
8291        case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8292                desc = "Target: Data Offset Error";
8293                break;
8294
8295        case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8296                desc = "Target: Too Much Write Data";
8297                break;
8298
8299        case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8300                desc = "Target: IU Too Short";
8301                break;
8302
8303        case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8304                desc = "Target: ACK NAK Timeout";
8305                break;
8306
8307        case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8308                desc = "Target: Nak Received";
8309                break;
8310
8311/****************************************************************************/
8312/*  Fibre Channel Direct Access values                                      */
8313/****************************************************************************/
8314
8315        case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8316                desc = "FC: Aborted";
8317                break;
8318
8319        case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8320                desc = "FC: RX ID Invalid";
8321                break;
8322
8323        case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8324                desc = "FC: DID Invalid";
8325                break;
8326
8327        case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8328                desc = "FC: Node Logged Out";
8329                break;
8330
8331        case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8332                desc = "FC: Exchange Canceled";
8333                break;
8334
8335/****************************************************************************/
8336/*  LAN values                                                              */
8337/****************************************************************************/
8338
8339        case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8340                desc = "LAN: Device not Found";
8341                break;
8342
8343        case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8344                desc = "LAN: Device Failure";
8345                break;
8346
8347        case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8348                desc = "LAN: Transmit Error";
8349                break;
8350
8351        case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8352                desc = "LAN: Transmit Aborted";
8353                break;
8354
8355        case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8356                desc = "LAN: Receive Error";
8357                break;
8358
8359        case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8360                desc = "LAN: Receive Aborted";
8361                break;
8362
8363        case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8364                desc = "LAN: Partial Packet";
8365                break;
8366
8367        case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8368                desc = "LAN: Canceled";
8369                break;
8370
8371/****************************************************************************/
8372/*  Serial Attached SCSI values                                             */
8373/****************************************************************************/
8374
8375        case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8376                desc = "SAS: SMP Request Failed";
8377                break;
8378
8379        case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8380                desc = "SAS: SMP Data Overrun";
8381                break;
8382
8383        default:
8384                desc = "Others";
8385                break;
8386        }
8387
8388        if (!desc)
8389                return;
8390
8391        dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8392            ioc->name, status, desc));
8393}
8394
8395/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8396EXPORT_SYMBOL(mpt_attach);
8397EXPORT_SYMBOL(mpt_detach);
8398#ifdef CONFIG_PM
8399EXPORT_SYMBOL(mpt_resume);
8400EXPORT_SYMBOL(mpt_suspend);
8401#endif
8402EXPORT_SYMBOL(ioc_list);
8403EXPORT_SYMBOL(mpt_register);
8404EXPORT_SYMBOL(mpt_deregister);
8405EXPORT_SYMBOL(mpt_event_register);
8406EXPORT_SYMBOL(mpt_event_deregister);
8407EXPORT_SYMBOL(mpt_reset_register);
8408EXPORT_SYMBOL(mpt_reset_deregister);
8409EXPORT_SYMBOL(mpt_device_driver_register);
8410EXPORT_SYMBOL(mpt_device_driver_deregister);
8411EXPORT_SYMBOL(mpt_get_msg_frame);
8412EXPORT_SYMBOL(mpt_put_msg_frame);
8413EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8414EXPORT_SYMBOL(mpt_free_msg_frame);
8415EXPORT_SYMBOL(mpt_send_handshake_request);
8416EXPORT_SYMBOL(mpt_verify_adapter);
8417EXPORT_SYMBOL(mpt_GetIocState);
8418EXPORT_SYMBOL(mpt_print_ioc_summary);
8419EXPORT_SYMBOL(mpt_HardResetHandler);
8420EXPORT_SYMBOL(mpt_config);
8421EXPORT_SYMBOL(mpt_findImVolumes);
8422EXPORT_SYMBOL(mpt_alloc_fw_memory);
8423EXPORT_SYMBOL(mpt_free_fw_memory);
8424EXPORT_SYMBOL(mptbase_sas_persist_operation);
8425EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8426
8427/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8428/**
8429 *      fusion_init - Fusion MPT base driver initialization routine.
8430 *
8431 *      Returns 0 for success, non-zero for failure.
8432 */
8433static int __init
8434fusion_init(void)
8435{
8436        u8 cb_idx;
8437
8438        show_mptmod_ver(my_NAME, my_VERSION);
8439        printk(KERN_INFO COPYRIGHT "\n");
8440
8441        for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8442                MptCallbacks[cb_idx] = NULL;
8443                MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8444                MptEvHandlers[cb_idx] = NULL;
8445                MptResetHandlers[cb_idx] = NULL;
8446        }
8447
8448        /*  Register ourselves (mptbase) in order to facilitate
8449         *  EventNotification handling.
8450         */
8451        mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER,
8452            "mptbase_reply");
8453
8454        /* Register for hard reset handling callbacks.
8455         */
8456        mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8457
8458#ifdef CONFIG_PROC_FS
8459        (void) procmpt_create();
8460#endif
8461        return 0;
8462}
8463
8464/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8465/**
8466 *      fusion_exit - Perform driver unload cleanup.
8467 *
8468 *      This routine frees all resources associated with each MPT adapter
8469 *      and removes all %MPT_PROCFS_MPTBASEDIR entries.
8470 */
8471static void __exit
8472fusion_exit(void)
8473{
8474
8475        mpt_reset_deregister(mpt_base_index);
8476
8477#ifdef CONFIG_PROC_FS
8478        procmpt_destroy();
8479#endif
8480}
8481
8482module_init(fusion_init);
8483module_exit(fusion_exit);
8484