Back to home page

OSCL-LXR

 
 

    


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