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