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