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