Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17

Linux/drivers/message/fusion/mptbase.c

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