Version:  2.0.40 2.2.26 2.4.37 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2

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