Version:  2.0.40 2.2.26 2.4.37 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8

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                 goto out_free_ioc;
1805         }
1806 
1807         /*
1808          * Setting up proper handlers for scatter gather handling
1809          */
1810         if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1811                 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1812                         ioc->add_sge = &mpt_add_sge_64bit_1078;
1813                 else
1814                         ioc->add_sge = &mpt_add_sge_64bit;
1815                 ioc->add_chain = &mpt_add_chain_64bit;
1816                 ioc->sg_addr_size = 8;
1817         } else {
1818                 ioc->add_sge = &mpt_add_sge;
1819                 ioc->add_chain = &mpt_add_chain;
1820                 ioc->sg_addr_size = 4;
1821         }
1822         ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1823 
1824         ioc->alloc_total = sizeof(MPT_ADAPTER);
1825         ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;           /* avoid div by zero! */
1826         ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1827 
1828 
1829         spin_lock_init(&ioc->taskmgmt_lock);
1830         mutex_init(&ioc->internal_cmds.mutex);
1831         init_completion(&ioc->internal_cmds.done);
1832         mutex_init(&ioc->mptbase_cmds.mutex);
1833         init_completion(&ioc->mptbase_cmds.done);
1834         mutex_init(&ioc->taskmgmt_cmds.mutex);
1835         init_completion(&ioc->taskmgmt_cmds.done);
1836 
1837         /* Initialize the event logging.
1838          */
1839         ioc->eventTypes = 0;    /* None */
1840         ioc->eventContext = 0;
1841         ioc->eventLogSize = 0;
1842         ioc->events = NULL;
1843 
1844 #ifdef MFCNT
1845         ioc->mfcnt = 0;
1846 #endif
1847 
1848         ioc->sh = NULL;
1849         ioc->cached_fw = NULL;
1850 
1851         /* Initialize SCSI Config Data structure
1852          */
1853         memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1854 
1855         /* Initialize the fc rport list head.
1856          */
1857         INIT_LIST_HEAD(&ioc->fc_rports);
1858 
1859         /* Find lookup slot. */
1860         INIT_LIST_HEAD(&ioc->list);
1861 
1862 
1863         /* Initialize workqueue */
1864         INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1865 
1866         snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1867                  "mpt_poll_%d", ioc->id);
1868         ioc->reset_work_q =
1869                 create_singlethread_workqueue(ioc->reset_work_q_name);
1870         if (!ioc->reset_work_q) {
1871                 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1872                     ioc->name);
1873                 r = -ENOMEM;
1874                 goto out_unmap_resources;
1875         }
1876 
1877         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1878             ioc->name, &ioc->facts, &ioc->pfacts[0]));
1879 
1880         ioc->prod_name = mpt_get_product_name(pdev->vendor, pdev->device,
1881                                               pdev->revision);
1882 
1883         switch (pdev->device)
1884         {
1885         case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1886         case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1887                 ioc->errata_flag_1064 = 1;
1888         case MPI_MANUFACTPAGE_DEVICEID_FC909:
1889         case MPI_MANUFACTPAGE_DEVICEID_FC929:
1890         case MPI_MANUFACTPAGE_DEVICEID_FC919:
1891         case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1892                 ioc->bus_type = FC;
1893                 break;
1894 
1895         case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1896                 if (pdev->revision < XL_929) {
1897                         /* 929X Chip Fix. Set Split transactions level
1898                         * for PCIX. Set MOST bits to zero.
1899                         */
1900                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1901                         pcixcmd &= 0x8F;
1902                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1903                 } else {
1904                         /* 929XL Chip Fix. Set MMRBC to 0x08.
1905                         */
1906                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1907                         pcixcmd |= 0x08;
1908                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1909                 }
1910                 ioc->bus_type = FC;
1911                 break;
1912 
1913         case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1914                 /* 919X Chip Fix. Set Split transactions level
1915                  * for PCIX. Set MOST bits to zero.
1916                  */
1917                 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1918                 pcixcmd &= 0x8F;
1919                 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1920                 ioc->bus_type = FC;
1921                 break;
1922 
1923         case MPI_MANUFACTPAGE_DEVID_53C1030:
1924                 /* 1030 Chip Fix. Disable Split transactions
1925                  * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1926                  */
1927                 if (pdev->revision < C0_1030) {
1928                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1929                         pcixcmd &= 0x8F;
1930                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1931                 }
1932 
1933         case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1934                 ioc->bus_type = SPI;
1935                 break;
1936 
1937         case MPI_MANUFACTPAGE_DEVID_SAS1064:
1938         case MPI_MANUFACTPAGE_DEVID_SAS1068:
1939                 ioc->errata_flag_1064 = 1;
1940                 ioc->bus_type = SAS;
1941                 break;
1942 
1943         case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1944         case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1945         case MPI_MANUFACTPAGE_DEVID_SAS1078:
1946                 ioc->bus_type = SAS;
1947                 break;
1948         }
1949 
1950 
1951         switch (ioc->bus_type) {
1952 
1953         case SAS:
1954                 ioc->msi_enable = mpt_msi_enable_sas;
1955                 break;
1956 
1957         case SPI:
1958                 ioc->msi_enable = mpt_msi_enable_spi;
1959                 break;
1960 
1961         case FC:
1962                 ioc->msi_enable = mpt_msi_enable_fc;
1963                 break;
1964 
1965         default:
1966                 ioc->msi_enable = 0;
1967                 break;
1968         }
1969 
1970         ioc->fw_events_off = 1;
1971 
1972         if (ioc->errata_flag_1064)
1973                 pci_disable_io_access(pdev);
1974 
1975         spin_lock_init(&ioc->FreeQlock);
1976 
1977         /* Disable all! */
1978         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1979         ioc->active = 0;
1980         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1981 
1982         /* Set IOC ptr in the pcidev's driver data. */
1983         pci_set_drvdata(ioc->pcidev, ioc);
1984 
1985         /* Set lookup ptr. */
1986         list_add_tail(&ioc->list, &ioc_list);
1987 
1988         /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1989          */
1990         mpt_detect_bound_ports(ioc, pdev);
1991 
1992         INIT_LIST_HEAD(&ioc->fw_event_list);
1993         spin_lock_init(&ioc->fw_event_lock);
1994         snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1995         ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1996         if (!ioc->fw_event_q) {
1997                 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1998                     ioc->name);
1999                 r = -ENOMEM;
2000                 goto out_remove_ioc;
2001         }
2002 
2003         if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2004             CAN_SLEEP)) != 0){
2005                 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
2006                     ioc->name, r);
2007 
2008                 destroy_workqueue(ioc->fw_event_q);
2009                 ioc->fw_event_q = NULL;
2010 
2011                 list_del(&ioc->list);
2012                 if (ioc->alt_ioc)
2013                         ioc->alt_ioc->alt_ioc = NULL;
2014                 iounmap(ioc->memmap);
2015                 if (pci_is_enabled(pdev))
2016                         pci_disable_device(pdev);
2017                 if (r != -5)
2018                         pci_release_selected_regions(pdev, ioc->bars);
2019 
2020                 destroy_workqueue(ioc->reset_work_q);
2021                 ioc->reset_work_q = NULL;
2022 
2023                 kfree(ioc);
2024                 return r;
2025         }
2026 
2027         /* call per device driver probe entry point */
2028         for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2029                 if(MptDeviceDriverHandlers[cb_idx] &&
2030                   MptDeviceDriverHandlers[cb_idx]->probe) {
2031                         MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
2032                 }
2033         }
2034 
2035 #ifdef CONFIG_PROC_FS
2036         /*
2037          *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
2038          */
2039         dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
2040         if (dent) {
2041                 proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc);
2042                 proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc);
2043         }
2044 #endif
2045 
2046         if (!ioc->alt_ioc)
2047                 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2048                         msecs_to_jiffies(MPT_POLLING_INTERVAL));
2049 
2050         return 0;
2051 
2052 out_remove_ioc:
2053         list_del(&ioc->list);
2054         if (ioc->alt_ioc)
2055                 ioc->alt_ioc->alt_ioc = NULL;
2056 
2057         destroy_workqueue(ioc->reset_work_q);
2058         ioc->reset_work_q = NULL;
2059 
2060 out_unmap_resources:
2061         iounmap(ioc->memmap);
2062         pci_disable_device(pdev);
2063         pci_release_selected_regions(pdev, ioc->bars);
2064 
2065 out_free_ioc:
2066         kfree(ioc);
2067 
2068         return r;
2069 }
2070 
2071 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2072 /**
2073  *      mpt_detach - Remove a PCI intelligent MPT adapter.
2074  *      @pdev: Pointer to pci_dev structure
2075  */
2076 
2077 void
2078 mpt_detach(struct pci_dev *pdev)
2079 {
2080         MPT_ADAPTER     *ioc = pci_get_drvdata(pdev);
2081         char pname[32];
2082         u8 cb_idx;
2083         unsigned long flags;
2084         struct workqueue_struct *wq;
2085 
2086         /*
2087          * Stop polling ioc for fault condition
2088          */
2089         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2090         wq = ioc->reset_work_q;
2091         ioc->reset_work_q = NULL;
2092         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2093         cancel_delayed_work(&ioc->fault_reset_work);
2094         destroy_workqueue(wq);
2095 
2096         spin_lock_irqsave(&ioc->fw_event_lock, flags);
2097         wq = ioc->fw_event_q;
2098         ioc->fw_event_q = NULL;
2099         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2100         destroy_workqueue(wq);
2101 
2102         sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2103         remove_proc_entry(pname, NULL);
2104         sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2105         remove_proc_entry(pname, NULL);
2106         sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2107         remove_proc_entry(pname, NULL);
2108 
2109         /* call per device driver remove entry point */
2110         for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2111                 if(MptDeviceDriverHandlers[cb_idx] &&
2112                   MptDeviceDriverHandlers[cb_idx]->remove) {
2113                         MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2114                 }
2115         }
2116 
2117         /* Disable interrupts! */
2118         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2119 
2120         ioc->active = 0;
2121         synchronize_irq(pdev->irq);
2122 
2123         /* Clear any lingering interrupt */
2124         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2125 
2126         CHIPREG_READ32(&ioc->chip->IntStatus);
2127 
2128         mpt_adapter_dispose(ioc);
2129 
2130 }
2131 
2132 /**************************************************************************
2133  * Power Management
2134  */
2135 #ifdef CONFIG_PM
2136 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2137 /**
2138  *      mpt_suspend - Fusion MPT base driver suspend routine.
2139  *      @pdev: Pointer to pci_dev structure
2140  *      @state: new state to enter
2141  */
2142 int
2143 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2144 {
2145         u32 device_state;
2146         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2147 
2148         device_state = pci_choose_state(pdev, state);
2149         printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2150             "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2151             device_state);
2152 
2153         /* put ioc into READY_STATE */
2154         if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2155                 printk(MYIOC_s_ERR_FMT
2156                 "pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
2157         }
2158 
2159         /* disable interrupts */
2160         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2161         ioc->active = 0;
2162 
2163         /* Clear any lingering interrupt */
2164         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2165 
2166         free_irq(ioc->pci_irq, ioc);
2167         if (ioc->msi_enable)
2168                 pci_disable_msi(ioc->pcidev);
2169         ioc->pci_irq = -1;
2170         pci_save_state(pdev);
2171         pci_disable_device(pdev);
2172         pci_release_selected_regions(pdev, ioc->bars);
2173         pci_set_power_state(pdev, device_state);
2174         return 0;
2175 }
2176 
2177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2178 /**
2179  *      mpt_resume - Fusion MPT base driver resume routine.
2180  *      @pdev: Pointer to pci_dev structure
2181  */
2182 int
2183 mpt_resume(struct pci_dev *pdev)
2184 {
2185         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2186         u32 device_state = pdev->current_state;
2187         int recovery_state;
2188         int err;
2189 
2190         printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2191             "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2192             device_state);
2193 
2194         pci_set_power_state(pdev, PCI_D0);
2195         pci_enable_wake(pdev, PCI_D0, 0);
2196         pci_restore_state(pdev);
2197         ioc->pcidev = pdev;
2198         err = mpt_mapresources(ioc);
2199         if (err)
2200                 return err;
2201 
2202         if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2203                 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2204                         ioc->add_sge = &mpt_add_sge_64bit_1078;
2205                 else
2206                         ioc->add_sge = &mpt_add_sge_64bit;
2207                 ioc->add_chain = &mpt_add_chain_64bit;
2208                 ioc->sg_addr_size = 8;
2209         } else {
2210 
2211                 ioc->add_sge = &mpt_add_sge;
2212                 ioc->add_chain = &mpt_add_chain;
2213                 ioc->sg_addr_size = 4;
2214         }
2215         ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2216 
2217         printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2218             ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2219             CHIPREG_READ32(&ioc->chip->Doorbell));
2220 
2221         /*
2222          * Errata workaround for SAS pci express:
2223          * Upon returning to the D0 state, the contents of the doorbell will be
2224          * stale data, and this will incorrectly signal to the host driver that
2225          * the firmware is ready to process mpt commands.   The workaround is
2226          * to issue a diagnostic reset.
2227          */
2228         if (ioc->bus_type == SAS && (pdev->device ==
2229             MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2230             MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2231                 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2232                         printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2233                             ioc->name);
2234                         goto out;
2235                 }
2236         }
2237 
2238         /* bring ioc to operational state */
2239         printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2240         recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2241                                                  CAN_SLEEP);
2242         if (recovery_state != 0)
2243                 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2244                     "error:[%x]\n", ioc->name, recovery_state);
2245         else
2246                 printk(MYIOC_s_INFO_FMT
2247                     "pci-resume: success\n", ioc->name);
2248  out:
2249         return 0;
2250 
2251 }
2252 #endif
2253 
2254 static int
2255 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2256 {
2257         if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2258              ioc->bus_type != SPI) ||
2259             (MptDriverClass[index] == MPTFC_DRIVER &&
2260              ioc->bus_type != FC) ||
2261             (MptDriverClass[index] == MPTSAS_DRIVER &&
2262              ioc->bus_type != SAS))
2263                 /* make sure we only call the relevant reset handler
2264                  * for the bus */
2265                 return 0;
2266         return (MptResetHandlers[index])(ioc, reset_phase);
2267 }
2268 
2269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2270 /**
2271  *      mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2272  *      @ioc: Pointer to MPT adapter structure
2273  *      @reason: Event word / reason
2274  *      @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2275  *
2276  *      This routine performs all the steps necessary to bring the IOC
2277  *      to a OPERATIONAL state.
2278  *
2279  *      This routine also pre-fetches the LAN MAC address of a Fibre Channel
2280  *      MPT adapter.
2281  *
2282  *      Returns:
2283  *               0 for success
2284  *              -1 if failed to get board READY
2285  *              -2 if READY but IOCFacts Failed
2286  *              -3 if READY but PrimeIOCFifos Failed
2287  *              -4 if READY but IOCInit Failed
2288  *              -5 if failed to enable_device and/or request_selected_regions
2289  *              -6 if failed to upload firmware
2290  */
2291 static int
2292 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2293 {
2294         int      hard_reset_done = 0;
2295         int      alt_ioc_ready = 0;
2296         int      hard;
2297         int      rc=0;
2298         int      ii;
2299         int      ret = 0;
2300         int      reset_alt_ioc_active = 0;
2301         int      irq_allocated = 0;
2302         u8      *a;
2303 
2304         printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2305             reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2306 
2307         /* Disable reply interrupts (also blocks FreeQ) */
2308         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2309         ioc->active = 0;
2310 
2311         if (ioc->alt_ioc) {
2312                 if (ioc->alt_ioc->active ||
2313                     reason == MPT_HOSTEVENT_IOC_RECOVER) {
2314                         reset_alt_ioc_active = 1;
2315                         /* Disable alt-IOC's reply interrupts
2316                          *  (and FreeQ) for a bit
2317                          **/
2318                         CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2319                                 0xFFFFFFFF);
2320                         ioc->alt_ioc->active = 0;
2321                 }
2322         }
2323 
2324         hard = 1;
2325         if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2326                 hard = 0;
2327 
2328         if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2329                 if (hard_reset_done == -4) {
2330                         printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2331                             ioc->name);
2332 
2333                         if (reset_alt_ioc_active && ioc->alt_ioc) {
2334                                 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2335                                 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2336                                     "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2337                                 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2338                                 ioc->alt_ioc->active = 1;
2339                         }
2340 
2341                 } else {
2342                         printk(MYIOC_s_WARN_FMT
2343                             "NOT READY WARNING!\n", ioc->name);
2344                 }
2345                 ret = -1;
2346                 goto out;
2347         }
2348 
2349         /* hard_reset_done = 0 if a soft reset was performed
2350          * and 1 if a hard reset was performed.
2351          */
2352         if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2353                 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2354                         alt_ioc_ready = 1;
2355                 else
2356                         printk(MYIOC_s_WARN_FMT
2357                             ": alt-ioc Not ready WARNING!\n",
2358                             ioc->alt_ioc->name);
2359         }
2360 
2361         for (ii=0; ii<5; ii++) {
2362                 /* Get IOC facts! Allow 5 retries */
2363                 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2364                         break;
2365         }
2366 
2367 
2368         if (ii == 5) {
2369                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2370                     "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2371                 ret = -2;
2372         } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2373                 MptDisplayIocCapabilities(ioc);
2374         }
2375 
2376         if (alt_ioc_ready) {
2377                 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2378                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2379                             "Initial Alt IocFacts failed rc=%x\n",
2380                             ioc->name, rc));
2381                         /* Retry - alt IOC was initialized once
2382                          */
2383                         rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2384                 }
2385                 if (rc) {
2386                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2387                             "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2388                         alt_ioc_ready = 0;
2389                         reset_alt_ioc_active = 0;
2390                 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2391                         MptDisplayIocCapabilities(ioc->alt_ioc);
2392                 }
2393         }
2394 
2395         if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2396             (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2397                 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2398                 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2399                     IORESOURCE_IO);
2400                 if (pci_enable_device(ioc->pcidev))
2401                         return -5;
2402                 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2403                         "mpt"))
2404                         return -5;
2405         }
2406 
2407         /*
2408          * Device is reset now. It must have de-asserted the interrupt line
2409          * (if it was asserted) and it should be safe to register for the
2410          * interrupt now.
2411          */
2412         if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2413                 ioc->pci_irq = -1;
2414                 if (ioc->pcidev->irq) {
2415                         if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2416                                 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2417                                     ioc->name);
2418                         else
2419                                 ioc->msi_enable = 0;
2420                         rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2421                             IRQF_SHARED, ioc->name, ioc);
2422                         if (rc < 0) {
2423                                 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2424                                     "interrupt %d!\n",
2425                                     ioc->name, ioc->pcidev->irq);
2426                                 if (ioc->msi_enable)
2427                                         pci_disable_msi(ioc->pcidev);
2428                                 ret = -EBUSY;
2429                                 goto out;
2430                         }
2431                         irq_allocated = 1;
2432                         ioc->pci_irq = ioc->pcidev->irq;
2433                         pci_set_master(ioc->pcidev);            /* ?? */
2434                         pci_set_drvdata(ioc->pcidev, ioc);
2435                         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2436                             "installed at interrupt %d\n", ioc->name,
2437                             ioc->pcidev->irq));
2438                 }
2439         }
2440 
2441         /* Prime reply & request queues!
2442          * (mucho alloc's) Must be done prior to
2443          * init as upper addresses are needed for init.
2444          * If fails, continue with alt-ioc processing
2445          */
2446         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2447             ioc->name));
2448         if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2449                 ret = -3;
2450 
2451         /* May need to check/upload firmware & data here!
2452          * If fails, continue with alt-ioc processing
2453          */
2454         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2455             ioc->name));
2456         if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2457                 ret = -4;
2458 // NEW!
2459         if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2460                 printk(MYIOC_s_WARN_FMT
2461                     ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2462                     ioc->alt_ioc->name, rc);
2463                 alt_ioc_ready = 0;
2464                 reset_alt_ioc_active = 0;
2465         }
2466 
2467         if (alt_ioc_ready) {
2468                 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2469                         alt_ioc_ready = 0;
2470                         reset_alt_ioc_active = 0;
2471                         printk(MYIOC_s_WARN_FMT
2472                                 ": alt-ioc: (%d) init failure WARNING!\n",
2473                                         ioc->alt_ioc->name, rc);
2474                 }
2475         }
2476 
2477         if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2478                 if (ioc->upload_fw) {
2479                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2480                             "firmware upload required!\n", ioc->name));
2481 
2482                         /* Controller is not operational, cannot do upload
2483                          */
2484                         if (ret == 0) {
2485                                 rc = mpt_do_upload(ioc, sleepFlag);
2486                                 if (rc == 0) {
2487                                         if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2488                                                 /*
2489                                                  * Maintain only one pointer to FW memory
2490                                                  * so there will not be two attempt to
2491                                                  * downloadboot onboard dual function
2492                                                  * chips (mpt_adapter_disable,
2493                                                  * mpt_diag_reset)
2494                                                  */
2495                                                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2496                                                     "mpt_upload:  alt_%s has cached_fw=%p \n",
2497                                                     ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2498                                                 ioc->cached_fw = NULL;
2499                                         }
2500                                 } else {
2501                                         printk(MYIOC_s_WARN_FMT
2502                                             "firmware upload failure!\n", ioc->name);
2503                                         ret = -6;
2504                                 }
2505                         }
2506                 }
2507         }
2508 
2509         /*  Enable MPT base driver management of EventNotification
2510          *  and EventAck handling.
2511          */
2512         if ((ret == 0) && (!ioc->facts.EventState)) {
2513                 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2514                         "SendEventNotification\n",
2515                     ioc->name));
2516                 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2517         }
2518 
2519         if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2520                 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2521 
2522         if (ret == 0) {
2523                 /* Enable! (reply interrupt) */
2524                 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2525                 ioc->active = 1;
2526         }
2527         if (rc == 0) {  /* alt ioc */
2528                 if (reset_alt_ioc_active && ioc->alt_ioc) {
2529                         /* (re)Enable alt-IOC! (reply interrupt) */
2530                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2531                                 "reply irq re-enabled\n",
2532                                 ioc->alt_ioc->name));
2533                         CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2534                                 MPI_HIM_DIM);
2535                         ioc->alt_ioc->active = 1;
2536                 }
2537         }
2538 
2539 
2540         /*      Add additional "reason" check before call to GetLanConfigPages
2541          *      (combined with GetIoUnitPage2 call).  This prevents a somewhat
2542          *      recursive scenario; GetLanConfigPages times out, timer expired
2543          *      routine calls HardResetHandler, which calls into here again,
2544          *      and we try GetLanConfigPages again...
2545          */
2546         if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2547 
2548                 /*
2549                  * Initialize link list for inactive raid volumes.
2550                  */
2551                 mutex_init(&ioc->raid_data.inactive_list_mutex);
2552                 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2553 
2554                 switch (ioc->bus_type) {
2555 
2556                 case SAS:
2557                         /* clear persistency table */
2558                         if(ioc->facts.IOCExceptions &
2559                             MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2560                                 ret = mptbase_sas_persist_operation(ioc,
2561                                     MPI_SAS_OP_CLEAR_NOT_PRESENT);
2562                                 if(ret != 0)
2563                                         goto out;
2564                         }
2565 
2566                         /* Find IM volumes
2567                          */
2568                         mpt_findImVolumes(ioc);
2569 
2570                         /* Check, and possibly reset, the coalescing value
2571                          */
2572                         mpt_read_ioc_pg_1(ioc);
2573 
2574                         break;
2575 
2576                 case FC:
2577                         if ((ioc->pfacts[0].ProtocolFlags &
2578                                 MPI_PORTFACTS_PROTOCOL_LAN) &&
2579                             (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2580                                 /*
2581                                  *  Pre-fetch the ports LAN MAC address!
2582                                  *  (LANPage1_t stuff)
2583                                  */
2584                                 (void) GetLanConfigPages(ioc);
2585                                 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2586                                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2587                                         "LanAddr = %02X:%02X:%02X"
2588                                         ":%02X:%02X:%02X\n",
2589                                         ioc->name, a[5], a[4],
2590                                         a[3], a[2], a[1], a[0]));
2591                         }
2592                         break;
2593 
2594                 case SPI:
2595                         /* Get NVRAM and adapter maximums from SPP 0 and 2
2596                          */
2597                         mpt_GetScsiPortSettings(ioc, 0);
2598 
2599                         /* Get version and length of SDP 1
2600                          */
2601                         mpt_readScsiDevicePageHeaders(ioc, 0);
2602 
2603                         /* Find IM volumes
2604                          */
2605                         if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2606                                 mpt_findImVolumes(ioc);
2607 
2608                         /* Check, and possibly reset, the coalescing value
2609                          */
2610                         mpt_read_ioc_pg_1(ioc);
2611 
2612                         mpt_read_ioc_pg_4(ioc);
2613 
2614                         break;
2615                 }
2616 
2617                 GetIoUnitPage2(ioc);
2618                 mpt_get_manufacturing_pg_0(ioc);
2619         }
2620 
2621  out:
2622         if ((ret != 0) && irq_allocated) {
2623                 free_irq(ioc->pci_irq, ioc);
2624                 if (ioc->msi_enable)
2625                         pci_disable_msi(ioc->pcidev);
2626         }
2627         return ret;
2628 }
2629 
2630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2631 /**
2632  *      mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2633  *      @ioc: Pointer to MPT adapter structure
2634  *      @pdev: Pointer to (struct pci_dev) structure
2635  *
2636  *      Search for PCI bus/dev_function which matches
2637  *      PCI bus/dev_function (+/-1) for newly discovered 929,
2638  *      929X, 1030 or 1035.
2639  *
2640  *      If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2641  *      using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2642  */
2643 static void
2644 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2645 {
2646         struct pci_dev *peer=NULL;
2647         unsigned int slot = PCI_SLOT(pdev->devfn);
2648         unsigned int func = PCI_FUNC(pdev->devfn);
2649         MPT_ADAPTER *ioc_srch;
2650 
2651         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2652             " searching for devfn match on %x or %x\n",
2653             ioc->name, pci_name(pdev), pdev->bus->number,
2654             pdev->devfn, func-1, func+1));
2655 
2656         peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2657         if (!peer) {
2658                 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2659                 if (!peer)
2660                         return;
2661         }
2662 
2663         list_for_each_entry(ioc_srch, &ioc_list, list) {
2664                 struct pci_dev *_pcidev = ioc_srch->pcidev;
2665                 if (_pcidev == peer) {
2666                         /* Paranoia checks */
2667                         if (ioc->alt_ioc != NULL) {
2668                                 printk(MYIOC_s_WARN_FMT
2669                                     "Oops, already bound (%s <==> %s)!\n",
2670                                     ioc->name, ioc->name, ioc->alt_ioc->name);
2671                                 break;
2672                         } else if (ioc_srch->alt_ioc != NULL) {
2673                                 printk(MYIOC_s_WARN_FMT
2674                                     "Oops, already bound (%s <==> %s)!\n",
2675                                     ioc_srch->name, ioc_srch->name,
2676                                     ioc_srch->alt_ioc->name);
2677                                 break;
2678                         }
2679                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2680                                 "FOUND! binding %s <==> %s\n",
2681                                 ioc->name, ioc->name, ioc_srch->name));
2682                         ioc_srch->alt_ioc = ioc;
2683                         ioc->alt_ioc = ioc_srch;
2684                 }
2685         }
2686         pci_dev_put(peer);
2687 }
2688 
2689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2690 /**
2691  *      mpt_adapter_disable - Disable misbehaving MPT adapter.
2692  *      @ioc: Pointer to MPT adapter structure
2693  */
2694 static void
2695 mpt_adapter_disable(MPT_ADAPTER *ioc)
2696 {
2697         int sz;
2698         int ret;
2699 
2700         if (ioc->cached_fw != NULL) {
2701                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2702                         "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2703                 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2704                     ioc->cached_fw, CAN_SLEEP)) < 0) {
2705                         printk(MYIOC_s_WARN_FMT
2706                             ": firmware downloadboot failure (%d)!\n",
2707                             ioc->name, ret);
2708                 }
2709         }
2710 
2711         /*
2712          * Put the controller into ready state (if its not already)
2713          */
2714         if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2715                 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2716                     CAN_SLEEP)) {
2717                         if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2718                                 printk(MYIOC_s_ERR_FMT "%s:  IOC msg unit "
2719                                     "reset failed to put ioc in ready state!\n",
2720                                     ioc->name, __func__);
2721                 } else
2722                         printk(MYIOC_s_ERR_FMT "%s:  IOC msg unit reset "
2723                             "failed!\n", ioc->name, __func__);
2724         }
2725 
2726 
2727         /* Disable adapter interrupts! */
2728         synchronize_irq(ioc->pcidev->irq);
2729         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2730         ioc->active = 0;
2731 
2732         /* Clear any lingering interrupt */
2733         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2734         CHIPREG_READ32(&ioc->chip->IntStatus);
2735 
2736         if (ioc->alloc != NULL) {
2737                 sz = ioc->alloc_sz;
2738                 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free  @ %p, sz=%d bytes\n",
2739                     ioc->name, ioc->alloc, ioc->alloc_sz));
2740                 pci_free_consistent(ioc->pcidev, sz,
2741                                 ioc->alloc, ioc->alloc_dma);
2742                 ioc->reply_frames = NULL;
2743                 ioc->req_frames = NULL;
2744                 ioc->alloc = NULL;
2745                 ioc->alloc_total -= sz;
2746         }
2747 
2748         if (ioc->sense_buf_pool != NULL) {
2749                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2750                 pci_free_consistent(ioc->pcidev, sz,
2751                                 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2752                 ioc->sense_buf_pool = NULL;
2753                 ioc->alloc_total -= sz;
2754         }
2755 
2756         if (ioc->events != NULL){
2757                 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2758                 kfree(ioc->events);
2759                 ioc->events = NULL;
2760                 ioc->alloc_total -= sz;
2761         }
2762 
2763         mpt_free_fw_memory(ioc);
2764 
2765         kfree(ioc->spi_data.nvram);
2766         mpt_inactive_raid_list_free(ioc);
2767         kfree(ioc->raid_data.pIocPg2);
2768         kfree(ioc->raid_data.pIocPg3);
2769         ioc->spi_data.nvram = NULL;
2770         ioc->raid_data.pIocPg3 = NULL;
2771 
2772         if (ioc->spi_data.pIocPg4 != NULL) {
2773                 sz = ioc->spi_data.IocPg4Sz;
2774                 pci_free_consistent(ioc->pcidev, sz,
2775                         ioc->spi_data.pIocPg4,
2776                         ioc->spi_data.IocPg4_dma);
2777                 ioc->spi_data.pIocPg4 = NULL;
2778                 ioc->alloc_total -= sz;
2779         }
2780 
2781         if (ioc->ReqToChain != NULL) {
2782                 kfree(ioc->ReqToChain);
2783                 kfree(ioc->RequestNB);
2784                 ioc->ReqToChain = NULL;
2785         }
2786 
2787         kfree(ioc->ChainToChain);
2788         ioc->ChainToChain = NULL;
2789 
2790         if (ioc->HostPageBuffer != NULL) {
2791                 if((ret = mpt_host_page_access_control(ioc,
2792                     MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2793                         printk(MYIOC_s_ERR_FMT
2794                            ": %s: host page buffers free failed (%d)!\n",
2795                             ioc->name, __func__, ret);
2796                 }
2797                 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2798                         "HostPageBuffer free  @ %p, sz=%d bytes\n",
2799                         ioc->name, ioc->HostPageBuffer,
2800                         ioc->HostPageBuffer_sz));
2801                 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2802                     ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2803                 ioc->HostPageBuffer = NULL;
2804                 ioc->HostPageBuffer_sz = 0;
2805                 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2806         }
2807 
2808         pci_set_drvdata(ioc->pcidev, NULL);
2809 }
2810 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2811 /**
2812  *      mpt_adapter_dispose - Free all resources associated with an MPT adapter
2813  *      @ioc: Pointer to MPT adapter structure
2814  *
2815  *      This routine unregisters h/w resources and frees all alloc'd memory
2816  *      associated with a MPT adapter structure.
2817  */
2818 static void
2819 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2820 {
2821         int sz_first, sz_last;
2822 
2823         if (ioc == NULL)
2824                 return;
2825 
2826         sz_first = ioc->alloc_total;
2827 
2828         mpt_adapter_disable(ioc);
2829 
2830         if (ioc->pci_irq != -1) {
2831                 free_irq(ioc->pci_irq, ioc);
2832                 if (ioc->msi_enable)
2833                         pci_disable_msi(ioc->pcidev);
2834                 ioc->pci_irq = -1;
2835         }
2836 
2837         if (ioc->memmap != NULL) {
2838                 iounmap(ioc->memmap);
2839                 ioc->memmap = NULL;
2840         }
2841 
2842         pci_disable_device(ioc->pcidev);
2843         pci_release_selected_regions(ioc->pcidev, ioc->bars);
2844 
2845         /*  Zap the adapter lookup ptr!  */
2846         list_del(&ioc->list);
2847 
2848         sz_last = ioc->alloc_total;
2849         dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2850             ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2851 
2852         if (ioc->alt_ioc)
2853                 ioc->alt_ioc->alt_ioc = NULL;
2854 
2855         kfree(ioc);
2856 }
2857 
2858 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2859 /**
2860  *      MptDisplayIocCapabilities - Disply IOC's capabilities.
2861  *      @ioc: Pointer to MPT adapter structure
2862  */
2863 static void
2864 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2865 {
2866         int i = 0;
2867 
2868         printk(KERN_INFO "%s: ", ioc->name);
2869         if (ioc->prod_name)
2870                 printk("%s: ", ioc->prod_name);
2871         printk("Capabilities={");
2872 
2873         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2874                 printk("Initiator");
2875                 i++;
2876         }
2877 
2878         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2879                 printk("%sTarget", i ? "," : "");
2880                 i++;
2881         }
2882 
2883         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2884                 printk("%sLAN", i ? "," : "");
2885                 i++;
2886         }
2887 
2888 #if 0
2889         /*
2890          *  This would probably evoke more questions than it's worth
2891          */
2892         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2893                 printk("%sLogBusAddr", i ? "," : "");
2894                 i++;
2895         }
2896 #endif
2897 
2898         printk("}\n");
2899 }
2900 
2901 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2902 /**
2903  *      MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2904  *      @ioc: Pointer to MPT_ADAPTER structure
2905  *      @force: Force hard KickStart of IOC
2906  *      @sleepFlag: Specifies whether the process can sleep
2907  *
2908  *      Returns:
2909  *               1 - DIAG reset and READY
2910  *               0 - READY initially OR soft reset and READY
2911  *              -1 - Any failure on KickStart
2912  *              -2 - Msg Unit Reset Failed
2913  *              -3 - IO Unit Reset Failed
2914  *              -4 - IOC owned by a PEER
2915  */
2916 static int
2917 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2918 {
2919         u32      ioc_state;
2920         int      statefault = 0;
2921         int      cntdn;
2922         int      hard_reset_done = 0;
2923         int      r;
2924         int      ii;
2925         int      whoinit;
2926 
2927         /* Get current [raw] IOC state  */
2928         ioc_state = mpt_GetIocState(ioc, 0);
2929         dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2930 
2931         /*
2932          *      Check to see if IOC got left/stuck in doorbell handshake
2933          *      grip of death.  If so, hard reset the IOC.
2934          */
2935         if (ioc_state & MPI_DOORBELL_ACTIVE) {
2936                 statefault = 1;
2937                 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2938                                 ioc->name);
2939         }
2940 
2941         /* Is it already READY? */
2942         if (!statefault &&
2943             ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2944                 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2945                     "IOC is in READY state\n", ioc->name));
2946                 return 0;
2947         }
2948 
2949         /*
2950          *      Check to see if IOC is in FAULT state.
2951          */
2952         if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2953                 statefault = 2;
2954                 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2955                     ioc->name);
2956                 printk(MYIOC_s_WARN_FMT "           FAULT code = %04xh\n",
2957                     ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2958         }
2959 
2960         /*
2961          *      Hmmm...  Did it get left operational?
2962          */
2963         if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2964                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2965                                 ioc->name));
2966 
2967                 /* Check WhoInit.
2968                  * If PCI Peer, exit.
2969                  * Else, if no fault conditions are present, issue a MessageUnitReset
2970                  * Else, fall through to KickStart case
2971                  */
2972                 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2973                 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2974                         "whoinit 0x%x statefault %d force %d\n",
2975                         ioc->name, whoinit, statefault, force));
2976                 if (whoinit == MPI_WHOINIT_PCI_PEER)
2977                         return -4;
2978                 else {
2979                         if ((statefault == 0 ) && (force == 0)) {
2980                                 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2981                                         return 0;
2982                         }
2983                         statefault = 3;
2984                 }
2985         }
2986 
2987         hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2988         if (hard_reset_done < 0)
2989                 return -1;
2990 
2991         /*
2992          *  Loop here waiting for IOC to come READY.
2993          */
2994         ii = 0;
2995         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5;     /* 5 seconds */
2996 
2997         while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2998                 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2999                         /*
3000                          *  BIOS or previous driver load left IOC in OP state.
3001                          *  Reset messaging FIFOs.
3002                          */
3003                         if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
3004                                 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
3005                                 return -2;
3006                         }
3007                 } else if (ioc_state == MPI_IOC_STATE_RESET) {
3008                         /*
3009                          *  Something is wrong.  Try to get IOC back
3010                          *  to a known state.
3011                          */
3012                         if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
3013                                 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
3014                                 return -3;
3015                         }
3016                 }
3017 
3018                 ii++; cntdn--;
3019                 if (!cntdn) {
3020                         printk(MYIOC_s_ERR_FMT
3021                                 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
3022                                 ioc->name, ioc_state, (int)((ii+5)/HZ));
3023                         return -ETIME;
3024                 }
3025 
3026                 if (sleepFlag == CAN_SLEEP) {
3027                         msleep(1);
3028                 } else {
3029                         mdelay (1);     /* 1 msec delay */
3030                 }
3031 
3032         }
3033 
3034         if (statefault < 3) {
3035                 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
3036                         statefault == 1 ? "stuck handshake" : "IOC FAULT");
3037         }
3038 
3039         return hard_reset_done;
3040 }
3041 
3042 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3043 /**
3044  *      mpt_GetIocState - Get the current state of a MPT adapter.
3045  *      @ioc: Pointer to MPT_ADAPTER structure
3046  *      @cooked: Request raw or cooked IOC state
3047  *
3048  *      Returns all IOC Doorbell register bits if cooked==0, else just the
3049  *      Doorbell bits in MPI_IOC_STATE_MASK.
3050  */
3051 u32
3052 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
3053 {
3054         u32 s, sc;
3055 
3056         /*  Get!  */
3057         s = CHIPREG_READ32(&ioc->chip->Doorbell);
3058         sc = s & MPI_IOC_STATE_MASK;
3059 
3060         /*  Save!  */
3061         ioc->last_state = sc;
3062 
3063         return cooked ? sc : s;
3064 }
3065 
3066 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3067 /**
3068  *      GetIocFacts - Send IOCFacts request to MPT adapter.
3069  *      @ioc: Pointer to MPT_ADAPTER structure
3070  *      @sleepFlag: Specifies whether the process can sleep
3071  *      @reason: If recovery, only update facts.
3072  *
3073  *      Returns 0 for success, non-zero for failure.
3074  */
3075 static int
3076 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3077 {
3078         IOCFacts_t               get_facts;
3079         IOCFactsReply_t         *facts;
3080         int                      r;
3081         int                      req_sz;
3082         int                      reply_sz;
3083         int                      sz;
3084         u32                      status, vv;
3085         u8                       shiftFactor=1;
3086 
3087         /* IOC *must* NOT be in RESET state! */
3088         if (ioc->last_state == MPI_IOC_STATE_RESET) {
3089                 printk(KERN_ERR MYNAM
3090                     ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3091                     ioc->name, ioc->last_state);
3092                 return -44;
3093         }
3094 
3095         facts = &ioc->facts;
3096 
3097         /* Destination (reply area)... */
3098         reply_sz = sizeof(*facts);
3099         memset(facts, 0, reply_sz);
3100 
3101         /* Request area (get_facts on the stack right now!) */
3102         req_sz = sizeof(get_facts);
3103         memset(&get_facts, 0, req_sz);
3104 
3105         get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3106         /* Assert: All other get_facts fields are zero! */
3107 
3108         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3109             "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3110             ioc->name, req_sz, reply_sz));
3111 
3112         /* No non-zero fields in the get_facts request are greater than
3113          * 1 byte in size, so we can just fire it off as is.
3114          */
3115         r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3116                         reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3117         if (r != 0)
3118                 return r;
3119 
3120         /*
3121          * Now byte swap (GRRR) the necessary fields before any further
3122          * inspection of reply contents.
3123          *
3124          * But need to do some sanity checks on MsgLength (byte) field
3125          * to make sure we don't zero IOC's req_sz!
3126          */
3127         /* Did we get a valid reply? */
3128         if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3129                 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3130                         /*
3131                          * If not been here, done that, save off first WhoInit value
3132                          */
3133                         if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3134                                 ioc->FirstWhoInit = facts->WhoInit;
3135                 }
3136 
3137                 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3138                 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3139                 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3140                 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3141                 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3142                 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3143                 /* CHECKME! IOCStatus, IOCLogInfo */
3144 
3145                 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3146                 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3147 
3148                 /*
3149                  * FC f/w version changed between 1.1 and 1.2
3150                  *      Old: u16{Major(4),Minor(4),SubMinor(8)}
3151                  *      New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3152                  */
3153                 if (facts->MsgVersion < MPI_VERSION_01_02) {
3154                         /*
3155                          *      Handle old FC f/w style, convert to new...
3156                          */
3157                         u16      oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3158                         facts->FWVersion.Word =
3159                                         ((oldv<<12) & 0xFF000000) |
3160                                         ((oldv<<8)  & 0x000FFF00);
3161                 } else
3162                         facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3163 
3164                 facts->ProductID = le16_to_cpu(facts->ProductID);
3165 
3166                 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3167                     > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3168                         ioc->ir_firmware = 1;
3169 
3170                 facts->CurrentHostMfaHighAddr =
3171                                 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3172                 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3173                 facts->CurrentSenseBufferHighAddr =
3174                                 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3175                 facts->CurReplyFrameSize =
3176                                 le16_to_cpu(facts->CurReplyFrameSize);
3177                 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3178 
3179                 /*
3180                  * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3181                  * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3182                  * to 14 in MPI-1.01.0x.
3183                  */
3184                 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3185                     facts->MsgVersion > MPI_VERSION_01_00) {
3186                         facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3187                 }
3188 
3189                 facts->FWImageSize = ALIGN(facts->FWImageSize, 4);
3190 
3191                 if (!facts->RequestFrameSize) {
3192                         /*  Something is wrong!  */
3193                         printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3194                                         ioc->name);
3195                         return -55;
3196                 }
3197 
3198                 r = sz = facts->BlockSize;
3199                 vv = ((63 / (sz * 4)) + 1) & 0x03;
3200                 ioc->NB_for_64_byte_frame = vv;
3201                 while ( sz )
3202                 {
3203                         shiftFactor++;
3204                         sz = sz >> 1;
3205                 }
3206                 ioc->NBShiftFactor  = shiftFactor;
3207                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3208                     "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3209                     ioc->name, vv, shiftFactor, r));
3210 
3211                 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3212                         /*
3213                          * Set values for this IOC's request & reply frame sizes,
3214                          * and request & reply queue depths...
3215                          */
3216                         ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3217                         ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3218                         ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3219                         ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3220 
3221                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3222                                 ioc->name, ioc->reply_sz, ioc->reply_depth));
3223                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz  =%3d, req_depth  =%4d\n",
3224                                 ioc->name, ioc->req_sz, ioc->req_depth));
3225 
3226                         /* Get port facts! */
3227                         if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3228                                 return r;
3229                 }
3230         } else {
3231                 printk(MYIOC_s_ERR_FMT
3232                      "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3233                      ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3234                      RequestFrameSize)/sizeof(u32)));
3235                 return -66;
3236         }
3237 
3238         return 0;
3239 }
3240 
3241 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3242 /**
3243  *      GetPortFacts - Send PortFacts request to MPT adapter.
3244  *      @ioc: Pointer to MPT_ADAPTER structure
3245  *      @portnum: Port number
3246  *      @sleepFlag: Specifies whether the process can sleep
3247  *
3248  *      Returns 0 for success, non-zero for failure.
3249  */
3250 static int
3251 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3252 {
3253         PortFacts_t              get_pfacts;
3254         PortFactsReply_t        *pfacts;
3255         int                      ii;
3256         int                      req_sz;
3257         int                      reply_sz;
3258         int                      max_id;
3259 
3260         /* IOC *must* NOT be in RESET state! */
3261         if (ioc->last_state == MPI_IOC_STATE_RESET) {
3262                 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3263                     ioc->name, ioc->last_state );
3264                 return -4;
3265         }
3266 
3267         pfacts = &ioc->pfacts[portnum];
3268 
3269         /* Destination (reply area)...  */
3270         reply_sz = sizeof(*pfacts);
3271         memset(pfacts, 0, reply_sz);
3272 
3273         /* Request area (get_pfacts on the stack right now!) */
3274         req_sz = sizeof(get_pfacts);
3275         memset(&get_pfacts, 0, req_sz);
3276 
3277         get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3278         get_pfacts.PortNumber = portnum;
3279         /* Assert: All other get_pfacts fields are zero! */
3280 
3281         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3282                         ioc->name, portnum));
3283 
3284         /* No non-zero fields in the get_pfacts request are greater than
3285          * 1 byte in size, so we can just fire it off as is.
3286          */
3287         ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3288                                 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3289         if (ii != 0)
3290                 return ii;
3291 
3292         /* Did we get a valid reply? */
3293 
3294         /* Now byte swap the necessary fields in the response. */
3295         pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3296         pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3297         pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3298         pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3299         pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3300         pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3301         pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3302         pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3303         pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3304 
3305         max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3306             pfacts->MaxDevices;
3307         ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3308         ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3309 
3310         /*
3311          * Place all the devices on channels
3312          *
3313          * (for debuging)
3314          */
3315         if (mpt_channel_mapping) {
3316                 ioc->devices_per_bus = 1;
3317                 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3318         }
3319 
3320         return 0;
3321 }
3322 
3323 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3324 /**
3325  *      SendIocInit - Send IOCInit request to MPT adapter.
3326  *      @ioc: Pointer to MPT_ADAPTER structure
3327  *      @sleepFlag: Specifies whether the process can sleep
3328  *
3329  *      Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3330  *
3331  *      Returns 0 for success, non-zero for failure.
3332  */
3333 static int
3334 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3335 {
3336         IOCInit_t                ioc_init;
3337         MPIDefaultReply_t        init_reply;
3338         u32                      state;
3339         int                      r;
3340         int                      count;
3341         int                      cntdn;
3342 
3343         memset(&ioc_init, 0, sizeof(ioc_init));
3344         memset(&init_reply, 0, sizeof(init_reply));
3345 
3346         ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3347         ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3348 
3349         /* If we are in a recovery mode and we uploaded the FW image,
3350          * then this pointer is not NULL. Skip the upload a second time.
3351          * Set this flag if cached_fw set for either IOC.
3352          */
3353         if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3354                 ioc->upload_fw = 1;
3355         else
3356                 ioc->upload_fw = 0;
3357         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3358                    ioc->name, ioc->upload_fw, ioc->facts.Flags));
3359 
3360         ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3361         ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3362 
3363         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3364                    ioc->name, ioc->facts.MsgVersion));
3365         if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3366                 // set MsgVersion and HeaderVersion host driver was built with
3367                 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3368                 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3369 
3370                 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3371                         ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3372                 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3373                         return -99;
3374         }
3375         ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);   /* in BYTES */
3376 
3377         if (ioc->sg_addr_size == sizeof(u64)) {
3378                 /* Save the upper 32-bits of the request
3379                  * (reply) and sense buffers.
3380                  */
3381                 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3382                 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3383         } else {
3384                 /* Force 32-bit addressing */
3385                 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3386                 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3387         }
3388 
3389         ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3390         ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3391         ioc->facts.MaxDevices = ioc_init.MaxDevices;
3392         ioc->facts.MaxBuses = ioc_init.MaxBuses;
3393 
3394         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3395                         ioc->name, &ioc_init));
3396 
3397         r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3398                                 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3399         if (r != 0) {
3400                 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3401                 return r;
3402         }
3403 
3404         /* No need to byte swap the multibyte fields in the reply
3405          * since we don't even look at its contents.
3406          */
3407 
3408         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3409                         ioc->name, &ioc_init));
3410 
3411         if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3412                 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3413                 return r;
3414         }
3415 
3416         /* YIKES!  SUPER IMPORTANT!!!
3417          *  Poll IocState until _OPERATIONAL while IOC is doing
3418          *  LoopInit and TargetDiscovery!
3419          */
3420         count = 0;
3421         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;    /* 60 seconds */
3422         state = mpt_GetIocState(ioc, 1);
3423         while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3424                 if (sleepFlag == CAN_SLEEP) {
3425                         msleep(1);
3426                 } else {
3427                         mdelay(1);
3428                 }
3429 
3430                 if (!cntdn) {
3431                         printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3432                                         ioc->name, (int)((count+5)/HZ));
3433                         return -9;
3434                 }
3435 
3436                 state = mpt_GetIocState(ioc, 1);
3437                 count++;
3438         }
3439         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3440                         ioc->name, count));
3441 
3442         ioc->aen_event_read_flag=0;
3443         return r;
3444 }
3445 
3446 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3447 /**
3448  *      SendPortEnable - Send PortEnable request to MPT adapter port.
3449  *      @ioc: Pointer to MPT_ADAPTER structure
3450  *      @portnum: Port number to enable
3451  *      @sleepFlag: Specifies whether the process can sleep
3452  *
3453  *      Send PortEnable to bring IOC to OPERATIONAL state.
3454  *
3455  *      Returns 0 for success, non-zero for failure.
3456  */
3457 static int
3458 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3459 {
3460         PortEnable_t             port_enable;
3461         MPIDefaultReply_t        reply_buf;
3462         int      rc;
3463         int      req_sz;
3464         int      reply_sz;
3465 
3466         /*  Destination...  */
3467         reply_sz = sizeof(MPIDefaultReply_t);
3468         memset(&reply_buf, 0, reply_sz);
3469 
3470         req_sz = sizeof(PortEnable_t);
3471         memset(&port_enable, 0, req_sz);
3472 
3473         port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3474         port_enable.PortNumber = portnum;
3475 /*      port_enable.ChainOffset = 0;            */
3476 /*      port_enable.MsgFlags = 0;               */
3477 /*      port_enable.MsgContext = 0;             */
3478 
3479         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3480                         ioc->name, portnum, &port_enable));
3481 
3482         /* RAID FW may take a long time to enable
3483          */
3484         if (ioc->ir_firmware || ioc->bus_type == SAS) {
3485                 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3486                 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3487                 300 /*seconds*/, sleepFlag);
3488         } else {
3489                 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3490                 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3491                 30 /*seconds*/, sleepFlag);
3492         }
3493         return rc;
3494 }
3495 
3496 /**
3497  *      mpt_alloc_fw_memory - allocate firmware memory
3498  *      @ioc: Pointer to MPT_ADAPTER structure
3499  *      @size: total FW bytes
3500  *
3501  *      If memory has already been allocated, the same (cached) value
3502  *      is returned.
3503  *
3504  *      Return 0 if successful, or non-zero for failure
3505  **/
3506 int
3507 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3508 {
3509         int rc;
3510 
3511         if (ioc->cached_fw) {
3512                 rc = 0;  /* use already allocated memory */
3513                 goto out;
3514         }
3515         else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3516                 ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
3517                 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3518                 rc = 0;
3519                 goto out;
3520         }
3521         ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3522         if (!ioc->cached_fw) {
3523                 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3524                     ioc->name);
3525                 rc = -1;
3526         } else {
3527                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3528                     ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3529                 ioc->alloc_total += size;
3530                 rc = 0;
3531         }
3532  out:
3533         return rc;
3534 }
3535 
3536 /**
3537  *      mpt_free_fw_memory - free firmware memory
3538  *      @ioc: Pointer to MPT_ADAPTER structure
3539  *
3540  *      If alt_img is NULL, delete from ioc structure.
3541  *      Else, delete a secondary image in same format.
3542  **/
3543 void
3544 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3545 {
3546         int sz;
3547 
3548         if (!ioc->cached_fw)
3549                 return;
3550 
3551         sz = ioc->facts.FWImageSize;
3552         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3553                  ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3554         pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3555         ioc->alloc_total -= sz;
3556         ioc->cached_fw = NULL;
3557 }
3558 
3559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3560 /**
3561  *      mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3562  *      @ioc: Pointer to MPT_ADAPTER structure
3563  *      @sleepFlag: Specifies whether the process can sleep
3564  *
3565  *      Returns 0 for success, >0 for handshake failure
3566  *              <0 for fw upload failure.
3567  *
3568  *      Remark: If bound IOC and a successful FWUpload was performed
3569  *      on the bound IOC, the second image is discarded
3570  *      and memory is free'd. Both channels must upload to prevent
3571  *      IOC from running in degraded mode.
3572  */
3573 static int
3574 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3575 {
3576         u8                       reply[sizeof(FWUploadReply_t)];
3577         FWUpload_t              *prequest;
3578         FWUploadReply_t         *preply;
3579         FWUploadTCSGE_t         *ptcsge;
3580         u32                      flagsLength;
3581         int                      ii, sz, reply_sz;
3582         int                      cmdStatus;
3583         int                     request_size;
3584         /* If the image size is 0, we are done.
3585          */
3586         if ((sz = ioc->facts.FWImageSize) == 0)
3587                 return 0;
3588 
3589         if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3590                 return -ENOMEM;
3591 
3592         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3593             ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3594 
3595         prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3596             kzalloc(ioc->req_sz, GFP_KERNEL);
3597         if (!prequest) {
3598                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3599                     "while allocating memory \n", ioc->name));
3600                 mpt_free_fw_memory(ioc);
3601                 return -ENOMEM;
3602         }
3603 
3604         preply = (FWUploadReply_t *)&reply;
3605 
3606         reply_sz = sizeof(reply);
3607         memset(preply, 0, reply_sz);
3608 
3609         prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3610         prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3611 
3612         ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3613         ptcsge->DetailsLength = 12;
3614         ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3615         ptcsge->ImageSize = cpu_to_le32(sz);
3616         ptcsge++;
3617 
3618         flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3619         ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3620         request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3621             ioc->SGE_size;
3622         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3623             " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3624             ioc->facts.FWImageSize, request_size));
3625         DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3626 
3627         ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3628             reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3629 
3630         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3631             "rc=%x \n", ioc->name, ii));
3632 
3633         cmdStatus = -EFAULT;
3634         if (ii == 0) {
3635                 /* Handshake transfer was complete and successful.
3636                  * Check the Reply Frame.
3637                  */
3638                 int status;
3639                 status = le16_to_cpu(preply->IOCStatus) &
3640                                 MPI_IOCSTATUS_MASK;
3641                 if (status == MPI_IOCSTATUS_SUCCESS &&
3642                     ioc->facts.FWImageSize ==
3643                     le32_to_cpu(preply->ActualImageSize))
3644                                 cmdStatus = 0;
3645         }
3646         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3647                         ioc->name, cmdStatus));
3648 
3649 
3650         if (cmdStatus) {
3651                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3652                     "freeing image \n", ioc->name));
3653                 mpt_free_fw_memory(ioc);
3654         }
3655         kfree(prequest);
3656 
3657         return cmdStatus;
3658 }
3659 
3660 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3661 /**
3662  *      mpt_downloadboot - DownloadBoot code
3663  *      @ioc: Pointer to MPT_ADAPTER structure
3664  *      @pFwHeader: Pointer to firmware header info
3665  *      @sleepFlag: Specifies whether the process can sleep
3666  *
3667  *      FwDownloadBoot requires Programmed IO access.
3668  *
3669  *      Returns 0 for success
3670  *              -1 FW Image size is 0
3671  *              -2 No valid cached_fw Pointer
3672  *              <0 for fw upload failure.
3673  */
3674 static int
3675 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3676 {
3677         MpiExtImageHeader_t     *pExtImage;
3678         u32                      fwSize;
3679         u32                      diag0val;
3680         int                      count;
3681         u32                     *ptrFw;
3682         u32                      diagRwData;
3683         u32                      nextImage;
3684         u32                      load_addr;
3685         u32                      ioc_state=0;
3686 
3687         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3688                                 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3689 
3690         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3691         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3692         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3693         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3694         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3695         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3696 
3697         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3698 
3699         /* wait 1 msec */
3700         if (sleepFlag == CAN_SLEEP) {
3701                 msleep(1);
3702         } else {
3703                 mdelay (1);
3704         }
3705 
3706         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3707         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3708 
3709         for (count = 0; count < 30; count ++) {
3710                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3711                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3712                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3713                                 ioc->name, count));
3714                         break;
3715                 }
3716                 /* wait .1 sec */
3717                 if (sleepFlag == CAN_SLEEP) {
3718                         msleep (100);
3719                 } else {
3720                         mdelay (100);
3721                 }
3722         }
3723 
3724         if ( count == 30 ) {
3725                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3726                 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3727                 ioc->name, diag0val));
3728                 return -3;
3729         }
3730 
3731         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3732         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3733         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3734         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3735         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3736         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3737 
3738         /* Set the DiagRwEn and Disable ARM bits */
3739         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3740 
3741         fwSize = (pFwHeader->ImageSize + 3)/4;
3742         ptrFw = (u32 *) pFwHeader;
3743 
3744         /* Write the LoadStartAddress to the DiagRw Address Register
3745          * using Programmed IO
3746          */
3747         if (ioc->errata_flag_1064)
3748                 pci_enable_io_access(ioc->pcidev);
3749 
3750         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3751         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3752                 ioc->name, pFwHeader->LoadStartAddress));
3753 
3754         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3755                                 ioc->name, fwSize*4, ptrFw));
3756         while (fwSize--) {
3757                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3758         }
3759 
3760         nextImage = pFwHeader->NextImageHeaderOffset;
3761         while (nextImage) {
3762                 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3763 
3764                 load_addr = pExtImage->LoadStartAddress;
3765 
3766                 fwSize = (pExtImage->ImageSize + 3) >> 2;
3767                 ptrFw = (u32 *)pExtImage;
3768 
3769                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3770                                                 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3771                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3772 
3773                 while (fwSize--) {
3774                         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3775                 }
3776                 nextImage = pExtImage->NextImageHeaderOffset;
3777         }
3778 
3779         /* Write the IopResetVectorRegAddr */
3780         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name,  pFwHeader->IopResetRegAddr));
3781         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3782 
3783         /* Write the IopResetVectorValue */
3784         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3785         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3786 
3787         /* Clear the internal flash bad bit - autoincrementing register,
3788          * so must do two writes.
3789          */
3790         if (ioc->bus_type == SPI) {
3791                 /*
3792                  * 1030 and 1035 H/W errata, workaround to access
3793                  * the ClearFlashBadSignatureBit
3794                  */
3795                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3796                 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3797                 diagRwData |= 0x40000000;
3798                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3799                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3800 
3801         } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3802                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3803                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3804                     MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3805 
3806                 /* wait 1 msec */
3807                 if (sleepFlag == CAN_SLEEP) {
3808                         msleep (1);
3809                 } else {
3810                         mdelay (1);
3811                 }
3812         }
3813 
3814         if (ioc->errata_flag_1064)
3815                 pci_disable_io_access(ioc->pcidev);
3816 
3817         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3818         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3819                 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3820                 ioc->name, diag0val));
3821         diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3822         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3823                 ioc->name, diag0val));
3824         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3825 
3826         /* Write 0xFF to reset the sequencer */
3827         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3828 
3829         if (ioc->bus_type == SAS) {
3830                 ioc_state = mpt_GetIocState(ioc, 0);
3831                 if ( (GetIocFacts(ioc, sleepFlag,
3832                                 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3833                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3834                                         ioc->name, ioc_state));
3835                         return -EFAULT;
3836                 }
3837         }
3838 
3839         for (count=0; count<HZ*20; count++) {
3840                 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3841                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3842                                 "downloadboot successful! (count=%d) IocState=%x\n",
3843                                 ioc->name, count, ioc_state));
3844                         if (ioc->bus_type == SAS) {
3845                                 return 0;
3846                         }
3847                         if ((SendIocInit(ioc, sleepFlag)) != 0) {
3848                                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3849                                         "downloadboot: SendIocInit failed\n",
3850                                         ioc->name));
3851                                 return -EFAULT;
3852                         }
3853                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3854                                         "downloadboot: SendIocInit successful\n",
3855                                         ioc->name));
3856                         return 0;
3857                 }
3858                 if (sleepFlag == CAN_SLEEP) {
3859                         msleep (10);
3860                 } else {
3861                         mdelay (10);
3862                 }
3863         }
3864         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3865                 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3866         return -EFAULT;
3867 }
3868 
3869 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3870 /**
3871  *      KickStart - Perform hard reset of MPT adapter.
3872  *      @ioc: Pointer to MPT_ADAPTER structure
3873  *      @force: Force hard reset
3874  *      @sleepFlag: Specifies whether the process can sleep
3875  *
3876  *      This routine places MPT adapter in diagnostic mode via the
3877  *      WriteSequence register, and then performs a hard reset of adapter
3878  *      via the Diagnostic register.
3879  *
3880  *      Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
3881  *                      or NO_SLEEP (interrupt thread, use mdelay)
3882  *                force - 1 if doorbell active, board fault state
3883  *                              board operational, IOC_RECOVERY or
3884  *                              IOC_BRINGUP and there is an alt_ioc.
3885  *                        0 else
3886  *
3887  *      Returns:
3888  *               1 - hard reset, READY
3889  *               0 - no reset due to History bit, READY
3890  *              -1 - no reset due to History bit but not READY
3891  *                   OR reset but failed to come READY
3892  *              -2 - no reset, could not enter DIAG mode
3893  *              -3 - reset but bad FW bit
3894  */
3895 static int
3896 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3897 {
3898         int hard_reset_done = 0;
3899         u32 ioc_state=0;
3900         int cnt,cntdn;
3901 
3902         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3903         if (ioc->bus_type == SPI) {
3904                 /* Always issue a Msg Unit Reset first. This will clear some
3905                  * SCSI bus hang conditions.
3906                  */
3907                 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3908 
3909                 if (sleepFlag == CAN_SLEEP) {
3910                         msleep (1000);
3911                 } else {
3912                         mdelay (1000);
3913                 }
3914         }
3915 
3916         hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3917         if (hard_reset_done < 0)
3918                 return hard_reset_done;
3919 
3920         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3921                 ioc->name));
3922 
3923         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;     /* 2 seconds */
3924         for (cnt=0; cnt<cntdn; cnt++) {
3925                 ioc_state = mpt_GetIocState(ioc, 1);
3926                 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3927                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3928                                         ioc->name, cnt));
3929                         return hard_reset_done;
3930                 }
3931                 if (sleepFlag == CAN_SLEEP) {
3932                         msleep (10);
3933                 } else {
3934                         mdelay (10);
3935                 }
3936         }
3937 
3938         dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3939                 ioc->name, mpt_GetIocState(ioc, 0)));
3940         return -1;
3941 }
3942 
3943 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3944 /**
3945  *      mpt_diag_reset - Perform hard reset of the adapter.
3946  *      @ioc: Pointer to MPT_ADAPTER structure
3947  *      @ignore: Set if to honor and clear to ignore
3948  *              the reset history bit
3949  *      @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3950  *              else set to NO_SLEEP (use mdelay instead)
3951  *
3952  *      This routine places the adapter in diagnostic mode via the
3953  *      WriteSequence register and then performs a hard reset of adapter
3954  *      via the Diagnostic register. Adapter should be in ready state
3955  *      upon successful completion.
3956  *
3957  *      Returns:  1  hard reset successful
3958  *                0  no reset performed because reset history bit set
3959  *               -2  enabling diagnostic mode failed
3960  *               -3  diagnostic reset failed
3961  */
3962 static int
3963 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3964 {
3965         u32 diag0val;
3966         u32 doorbell;
3967         int hard_reset_done = 0;
3968         int count = 0;
3969         u32 diag1val = 0;
3970         MpiFwHeader_t *cached_fw;       /* Pointer to FW */
3971         u8       cb_idx;
3972 
3973         /* Clear any existing interrupts */
3974         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3975 
3976         if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3977 
3978                 if (!ignore)
3979                         return 0;
3980 
3981                 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3982                         "address=%p\n",  ioc->name, __func__,
3983                         &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3984                 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3985                 if (sleepFlag == CAN_SLEEP)
3986                         msleep(1);
3987                 else
3988                         mdelay(1);
3989 
3990                 /*
3991                  * Call each currently registered protocol IOC reset handler
3992                  * with pre-reset indication.
3993                  * NOTE: If we're doing _IOC_BRINGUP, there can be no
3994                  * MptResetHandlers[] registered yet.
3995                  */
3996                 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3997                         if (MptResetHandlers[cb_idx])
3998                                 (*(MptResetHandlers[cb_idx]))(ioc,
3999                                                 MPT_IOC_PRE_RESET);
4000                 }
4001 
4002                 for (count = 0; count < 60; count ++) {
4003                         doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4004                         doorbell &= MPI_IOC_STATE_MASK;
4005 
4006                         drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4007                                 "looking for READY STATE: doorbell=%x"
4008                                 " count=%d\n",
4009                                 ioc->name, doorbell, count));
4010 
4011                         if (doorbell == MPI_IOC_STATE_READY) {
4012                                 return 1;
4013                         }
4014 
4015                         /* wait 1 sec */
4016                         if (sleepFlag == CAN_SLEEP)
4017                                 msleep(1000);
4018                         else
4019                                 mdelay(1000);
4020                 }
4021                 return -1;
4022         }
4023 
4024         /* Use "Diagnostic reset" method! (only thing available!) */
4025         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4026 
4027         if (ioc->debug_level & MPT_DEBUG) {
4028                 if (ioc->alt_ioc)
4029                         diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4030                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
4031                         ioc->name, diag0val, diag1val));
4032         }
4033 
4034         /* Do the reset if we are told to ignore the reset history
4035          * or if the reset history is 0
4036          */
4037         if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
4038                 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4039                         /* Write magic sequence to WriteSequence register
4040                          * Loop until in diagnostic mode
4041                          */
4042                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4043                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4044                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4045                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4046                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4047                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4048 
4049                         /* wait 100 msec */
4050                         if (sleepFlag == CAN_SLEEP) {
4051                                 msleep (100);
4052                         } else {
4053                                 mdelay (100);
4054                         }
4055 
4056                         count++;
4057                         if (count > 20) {
4058                                 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4059                                                 ioc->name, diag0val);
4060                                 return -2;
4061 
4062                         }
4063 
4064                         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4065 
4066                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4067                                         ioc->name, diag0val));
4068                 }
4069 
4070                 if (ioc->debug_level & MPT_DEBUG) {
4071                         if (ioc->alt_ioc)
4072                                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4073                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4074                                 ioc->name, diag0val, diag1val));
4075                 }
4076                 /*
4077                  * Disable the ARM (Bug fix)
4078                  *
4079                  */
4080                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4081                 mdelay(1);
4082 
4083                 /*
4084                  * Now hit the reset bit in the Diagnostic register
4085                  * (THE BIG HAMMER!) (Clears DRWE bit).
4086                  */
4087                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4088                 hard_reset_done = 1;
4089                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4090                                 ioc->name));
4091 
4092                 /*
4093                  * Call each currently registered protocol IOC reset handler
4094                  * with pre-reset indication.
4095                  * NOTE: If we're doing _IOC_BRINGUP, there can be no
4096                  * MptResetHandlers[] registered yet.
4097                  */
4098                 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4099                         if (MptResetHandlers[cb_idx]) {
4100                                 mpt_signal_reset(cb_idx,
4101                                         ioc, MPT_IOC_PRE_RESET);
4102                                 if (ioc->alt_ioc) {
4103                                         mpt_signal_reset(cb_idx,
4104                                         ioc->alt_ioc, MPT_IOC_PRE_RESET);
4105                                 }
4106                         }
4107                 }
4108 
4109                 if (ioc->cached_fw)
4110                         cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4111                 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4112                         cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4113                 else
4114                         cached_fw = NULL;
4115                 if (cached_fw) {
4116                         /* If the DownloadBoot operation fails, the
4117                          * IOC will be left unusable. This is a fatal error
4118                          * case.  _diag_reset will return < 0
4119                          */
4120                         for (count = 0; count < 30; count ++) {
4121                                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4122                                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4123                                         break;
4124                                 }
4125 
4126                                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4127                                         ioc->name, diag0val, count));
4128                                 /* wait 1 sec */
4129                                 if (sleepFlag == CAN_SLEEP) {
4130                                         msleep (1000);
4131                                 } else {
4132                                         mdelay (1000);
4133                                 }
4134                         }
4135                         if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4136                                 printk(MYIOC_s_WARN_FMT
4137                                         "firmware downloadboot failure (%d)!\n", ioc->name, count);
4138                         }
4139 
4140                 } else {
4141                         /* Wait for FW to reload and for board
4142                          * to go to the READY state.
4143                          * Maximum wait is 60 seconds.
4144                          * If fail, no error will check again
4145                          * with calling program.
4146                          */
4147                         for (count = 0; count < 60; count ++) {
4148                                 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4149                                 doorbell &= MPI_IOC_STATE_MASK;
4150 
4151                                 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4152                                     "looking for READY STATE: doorbell=%x"
4153                                     " count=%d\n", ioc->name, doorbell, count));
4154 
4155                                 if (doorbell == MPI_IOC_STATE_READY) {
4156                                         break;
4157                                 }
4158 
4159                                 /* wait 1 sec */
4160                                 if (sleepFlag == CAN_SLEEP) {
4161                                         msleep (1000);
4162                                 } else {
4163                                         mdelay (1000);
4164                                 }
4165                         }
4166 
4167                         if (doorbell != MPI_IOC_STATE_READY)
4168                                 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4169                                     "after reset! IocState=%x", ioc->name,
4170                                     doorbell);
4171                 }
4172         }
4173 
4174         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4175         if (ioc->debug_level & MPT_DEBUG) {
4176                 if (ioc->alt_ioc)
4177                         diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4178                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4179                         ioc->name, diag0val, diag1val));
4180         }
4181 
4182         /* Clear RESET_HISTORY bit!  Place board in the
4183          * diagnostic mode to update the diag register.
4184          */
4185         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4186         count = 0;
4187         while ((diag0val & MPI_DIAG_DRWE) == 0) {
4188                 /* Write magic sequence to WriteSequence register
4189                  * Loop until in diagnostic mode
4190                  */
4191                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4192                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4193                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4194                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4195                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4196                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4197 
4198                 /* wait 100 msec */
4199                 if (sleepFlag == CAN_SLEEP) {
4200                         msleep (100);
4201                 } else {
4202                         mdelay (100);
4203                 }
4204 
4205                 count++;
4206                 if (count > 20) {
4207                         printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4208                                         ioc->name, diag0val);
4209                         break;
4210                 }
4211                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4212         }
4213         diag0val &= ~MPI_DIAG_RESET_HISTORY;
4214         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4215         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4216         if (diag0val & MPI_DIAG_RESET_HISTORY) {
4217                 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4218                                 ioc->name);
4219         }
4220 
4221         /* Disable Diagnostic Mode
4222          */
4223         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4224 
4225         /* Check FW reload status flags.
4226          */
4227         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4228         if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4229                 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4230                                 ioc->name, diag0val);
4231                 return -3;
4232         }
4233 
4234         if (ioc->debug_level & MPT_DEBUG) {
4235                 if (ioc->alt_ioc)
4236                         diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4237                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4238                         ioc->name, diag0val, diag1val));
4239         }
4240 
4241         /*
4242          * Reset flag that says we've enabled event notification
4243          */
4244         ioc->facts.EventState = 0;
4245 
4246         if (ioc->alt_ioc)
4247                 ioc->alt_ioc->facts.EventState = 0;
4248 
4249         return hard_reset_done;
4250 }
4251 
4252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4253 /**
4254  *      SendIocReset - Send IOCReset request to MPT adapter.
4255  *      @ioc: Pointer to MPT_ADAPTER structure
4256  *      @reset_type: reset type, expected values are
4257  *      %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4258  *      @sleepFlag: Specifies whether the process can sleep
4259  *
4260  *      Send IOCReset request to the MPT adapter.
4261  *
4262  *      Returns 0 for success, non-zero for failure.
4263  */
4264 static int
4265 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4266 {
4267         int r;
4268         u32 state;
4269         int cntdn, count;
4270 
4271         drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4272                         ioc->name, reset_type));
4273         CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4274         if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4275                 return r;
4276 
4277         /* FW ACK'd request, wait for READY state
4278          */
4279         count = 0;
4280         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;    /* 15 seconds */
4281 
4282         while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4283                 cntdn--;
4284                 count++;
4285                 if (!cntdn) {
4286                         if (sleepFlag != CAN_SLEEP)
4287                                 count *= 10;
4288 
4289                         printk(MYIOC_s_ERR_FMT
4290                             "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4291                             ioc->name, state, (int)((count+5)/HZ));
4292                         return -ETIME;
4293                 }
4294 
4295                 if (sleepFlag == CAN_SLEEP) {
4296                         msleep(1);
4297                 } else {
4298                         mdelay (1);     /* 1 msec delay */
4299                 }
4300         }
4301 
4302         /* TODO!
4303          *  Cleanup all event stuff for this IOC; re-issue EventNotification
4304          *  request if needed.
4305          */
4306         if (ioc->facts.Function)
4307                 ioc->facts.EventState = 0;
4308 
4309         return 0;
4310 }
4311 
4312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4313 /**
4314  *      initChainBuffers - Allocate memory for and initialize chain buffers
4315  *      @ioc: Pointer to MPT_ADAPTER structure
4316  *
4317  *      Allocates memory for and initializes chain buffers,
4318  *      chain buffer control arrays and spinlock.
4319  */
4320 static int
4321 initChainBuffers(MPT_ADAPTER *ioc)
4322 {
4323         u8              *mem;
4324         int             sz, ii, num_chain;
4325         int             scale, num_sge, numSGE;
4326 
4327         /* ReqToChain size must equal the req_depth
4328          * index = req_idx
4329          */
4330         if (ioc->ReqToChain == NULL) {
4331                 sz = ioc->req_depth * sizeof(int);
4332                 mem = kmalloc(sz, GFP_ATOMIC);
4333                 if (mem == NULL)
4334                         return -1;
4335 
4336                 ioc->ReqToChain = (int *) mem;
4337                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc  @ %p, sz=%d bytes\n",
4338                                 ioc->name, mem, sz));
4339                 mem = kmalloc(sz, GFP_ATOMIC);
4340                 if (mem == NULL)
4341                         return -1;
4342 
4343                 ioc->RequestNB = (int *) mem;
4344                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc  @ %p, sz=%d bytes\n",
4345                                 ioc->name, mem, sz));
4346         }
4347         for (ii = 0; ii < ioc->req_depth; ii++) {
4348                 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4349         }
4350 
4351         /* ChainToChain size must equal the total number
4352          * of chain buffers to be allocated.
4353          * index = chain_idx
4354          *
4355          * Calculate the number of chain buffers needed(plus 1) per I/O
4356          * then multiply the maximum number of simultaneous cmds
4357          *
4358          * num_sge = num sge in request frame + last chain buffer
4359          * scale = num sge per chain buffer if no chain element
4360          */
4361         scale = ioc->req_sz / ioc->SGE_size;
4362         if (ioc->sg_addr_size == sizeof(u64))
4363                 num_sge =  scale + (ioc->req_sz - 60) / ioc->SGE_size;
4364         else
4365                 num_sge =  1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4366 
4367         if (ioc->sg_addr_size == sizeof(u64)) {
4368                 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4369                         (ioc->req_sz - 60) / ioc->SGE_size;
4370         } else {
4371                 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4372                     scale + (ioc->req_sz - 64) / ioc->SGE_size;
4373         }
4374         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4375                 ioc->name, num_sge, numSGE));
4376 
4377         if (ioc->bus_type == FC) {
4378                 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4379                         numSGE = MPT_SCSI_FC_SG_DEPTH;
4380         } else {
4381                 if (numSGE > MPT_SCSI_SG_DEPTH)
4382                         numSGE = MPT_SCSI_SG_DEPTH;
4383         }
4384 
4385         num_chain = 1;
4386         while (numSGE - num_sge > 0) {
4387                 num_chain++;
4388                 num_sge += (scale - 1);
4389         }
4390         num_chain++;
4391 
4392         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4393                 ioc->name, numSGE, num_sge, num_chain));
4394 
4395         if (ioc->bus_type == SPI)
4396                 num_chain *= MPT_SCSI_CAN_QUEUE;
4397         else if (ioc->bus_type == SAS)
4398                 num_chain *= MPT_SAS_CAN_QUEUE;
4399         else
4400                 num_chain *= MPT_FC_CAN_QUEUE;
4401 
4402         ioc->num_chain = num_chain;
4403 
4404         sz = num_chain * sizeof(int);
4405         if (ioc->ChainToChain == NULL) {
4406                 mem = kmalloc(sz, GFP_ATOMIC);
4407                 if (mem == NULL)
4408                         return -1;
4409 
4410                 ioc->ChainToChain = (int *) mem;
4411                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4412                                 ioc->name, mem, sz));
4413         } else {
4414                 mem = (u8 *) ioc->ChainToChain;
4415         }
4416         memset(mem, 0xFF, sz);
4417         return num_chain;
4418 }
4419 
4420 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4421 /**
4422  *      PrimeIocFifos - Initialize IOC request and reply FIFOs.
4423  *      @ioc: Pointer to MPT_ADAPTER structure
4424  *
4425  *      This routine allocates memory for the MPT reply and request frame
4426  *      pools (if necessary), and primes the IOC reply FIFO with
4427  *      reply frames.
4428  *
4429  *      Returns 0 for success, non-zero for failure.
4430  */
4431 static int
4432 PrimeIocFifos(MPT_ADAPTER *ioc)
4433 {
4434         MPT_FRAME_HDR *mf;
4435         unsigned long flags;
4436         dma_addr_t alloc_dma;
4437         u8 *mem;
4438         int i, reply_sz, sz, total_size, num_chain;
4439         u64     dma_mask;
4440 
4441         dma_mask = 0;
4442 
4443         /*  Prime reply FIFO...  */
4444 
4445         if (ioc->reply_frames == NULL) {
4446                 if ( (num_chain = initChainBuffers(ioc)) < 0)
4447                         return -1;
4448                 /*
4449                  * 1078 errata workaround for the 36GB limitation
4450                  */
4451                 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4452                     ioc->dma_mask > DMA_BIT_MASK(35)) {
4453                         if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4454                             && !pci_set_consistent_dma_mask(ioc->pcidev,
4455                             DMA_BIT_MASK(32))) {
4456                                 dma_mask = DMA_BIT_MASK(35);
4457                                 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4458                                     "setting 35 bit addressing for "
4459                                     "Request/Reply/Chain and Sense Buffers\n",
4460                                     ioc->name));
4461                         } else {
4462                                 /*Reseting DMA mask to 64 bit*/
4463                                 pci_set_dma_mask(ioc->pcidev,
4464                                         DMA_BIT_MASK(64));
4465                                 pci_set_consistent_dma_mask(ioc->pcidev,
4466                                         DMA_BIT_MASK(64));
4467 
4468                                 printk(MYIOC_s_ERR_FMT
4469                                     "failed setting 35 bit addressing for "
4470                                     "Request/Reply/Chain and Sense Buffers\n",
4471                                     ioc->name);
4472                                 return -1;
4473                         }
4474                 }
4475 
4476                 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4477                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4478                                 ioc->name, ioc->reply_sz, ioc->reply_depth));
4479                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4480                                 ioc->name, reply_sz, reply_sz));
4481 
4482                 sz = (ioc->req_sz * ioc->req_depth);
4483                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4484                                 ioc->name, ioc->req_sz, ioc->req_depth));
4485                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4486                                 ioc->name, sz, sz));
4487                 total_size += sz;
4488 
4489                 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4490                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4491                                 ioc->name, ioc->req_sz, num_chain));
4492                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4493                                 ioc->name, sz, sz, num_chain));
4494 
4495                 total_size += sz;
4496                 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4497                 if (mem == NULL) {
4498                         printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4499                                 ioc->name);
4500                         goto out_fail;
4501                 }
4502 
4503                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4504                                 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4505 
4506                 memset(mem, 0, total_size);
4507                 ioc->alloc_total += total_size;
4508                 ioc->alloc = mem;
4509                 ioc->alloc_dma = alloc_dma;
4510                 ioc->alloc_sz = total_size;
4511                 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4512                 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4513 
4514                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4515                         ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4516 
4517                 alloc_dma += reply_sz;
4518                 mem += reply_sz;
4519 
4520                 /*  Request FIFO - WE manage this!  */
4521 
4522                 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4523                 ioc->req_frames_dma = alloc_dma;
4524 
4525                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4526                                 ioc->name, mem, (void *)(ulong)alloc_dma));
4527 
4528                 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4529 
4530                 for (i = 0; i < ioc->req_depth; i++) {
4531                         alloc_dma += ioc->req_sz;
4532                         mem += ioc->req_sz;
4533                 }
4534 
4535                 ioc->ChainBuffer = mem;
4536                 ioc->ChainBufferDMA = alloc_dma;
4537 
4538                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4539                         ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4540 
4541                 /* Initialize the free chain Q.
4542                 */
4543 
4544                 INIT_LIST_HEAD(&ioc->FreeChainQ);
4545 
4546                 /* Post the chain buffers to the FreeChainQ.
4547                 */
4548                 mem = (u8 *)ioc->ChainBuffer;
4549                 for (i=0; i < num_chain; i++) {
4550                         mf = (MPT_FRAME_HDR *) mem;
4551                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4552                         mem += ioc->req_sz;
4553                 }
4554 
4555                 /* Initialize Request frames linked list
4556                  */
4557                 alloc_dma = ioc->req_frames_dma;
4558                 mem = (u8 *) ioc->req_frames;
4559 
4560                 spin_lock_irqsave(&ioc->FreeQlock, flags);
4561                 INIT_LIST_HEAD(&ioc->FreeQ);
4562                 for (i = 0; i < ioc->req_depth; i++) {
4563                         mf = (MPT_FRAME_HDR *) mem;
4564 
4565                         /*  Queue REQUESTs *internally*!  */
4566                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4567 
4568                         mem += ioc->req_sz;
4569                 }
4570                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4571 
4572                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4573                 ioc->sense_buf_pool =
4574                         pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4575                 if (ioc->sense_buf_pool == NULL) {
4576                         printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4577                                 ioc->name);
4578                         goto out_fail;
4579                 }
4580 
4581                 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4582                 ioc->alloc_total += sz;
4583                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4584                         ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4585 
4586         }
4587 
4588         /* Post Reply frames to FIFO
4589          */
4590         alloc_dma = ioc->alloc_dma;
4591         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4592                 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4593 
4594         for (i = 0; i < ioc->reply_depth; i++) {
4595                 /*  Write each address to the IOC!  */
4596                 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4597                 alloc_dma += ioc->reply_sz;
4598         }
4599 
4600         if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4601             ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4602             ioc->dma_mask))
4603                 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4604                     "restoring 64 bit addressing\n", ioc->name));
4605 
4606         return 0;
4607 
4608 out_fail:
4609 
4610         if (ioc->alloc != NULL) {
4611                 sz = ioc->alloc_sz;
4612                 pci_free_consistent(ioc->pcidev,
4613                                 sz,
4614                                 ioc->alloc, ioc->alloc_dma);
4615                 ioc->reply_frames = NULL;
4616                 ioc->req_frames = NULL;
4617                 ioc->alloc_total -= sz;
4618         }
4619         if (ioc->sense_buf_pool != NULL) {
4620                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4621                 pci_free_consistent(ioc->pcidev,
4622                                 sz,
4623                                 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4624                 ioc->sense_buf_pool = NULL;
4625         }
4626 
4627         if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4628             DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4629             DMA_BIT_MASK(64)))
4630                 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4631                     "restoring 64 bit addressing\n", ioc->name));
4632 
4633         return -1;
4634 }
4635 
4636 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4637 /**
4638  *      mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4639  *      from IOC via doorbell handshake method.
4640  *      @ioc: Pointer to MPT_ADAPTER structure
4641  *      @reqBytes: Size of the request in bytes
4642  *      @req: Pointer to MPT request frame
4643  *      @replyBytes: Expected size of the reply in bytes
4644  *      @u16reply: Pointer to area where reply should be written
4645  *      @maxwait: Max wait time for a reply (in seconds)
4646  *      @sleepFlag: Specifies whether the process can sleep
4647  *
4648  *      NOTES: It is the callers responsibility to byte-swap fields in the
4649  *      request which are greater than 1 byte in size.  It is also the
4650  *      callers responsibility to byte-swap response fields which are
4651  *      greater than 1 byte in size.
4652  *
4653  *      Returns 0 for success, non-zero for failure.
4654  */
4655 static int
4656 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4657                 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4658 {
4659         MPIDefaultReply_t *mptReply;
4660         int failcnt = 0;
4661         int t;
4662 
4663         /*
4664          * Get ready to cache a handshake reply
4665          */
4666         ioc->hs_reply_idx = 0;
4667         mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4668         mptReply->MsgLength = 0;
4669 
4670         /*
4671          * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4672          * then tell IOC that we want to handshake a request of N words.
4673          * (WRITE u32val to Doorbell reg).
4674          */
4675         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4676         CHIPREG_WRITE32(&ioc->chip->Doorbell,
4677                         ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4678                          ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4679 
4680         /*
4681          * Wait for IOC's doorbell handshake int
4682          */
4683         if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4684                 failcnt++;
4685 
4686         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4687                         ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4688 
4689         /* Read doorbell and check for active bit */
4690         if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4691                         return -1;
4692 
4693         /*
4694          * Clear doorbell int (WRITE 0 to IntStatus reg),
4695          * then wait for IOC to ACKnowledge that it's ready for
4696          * our handshake request.
4697          */
4698         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4699         if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4700                 failcnt++;
4701 
4702         if (!failcnt) {
4703                 int      ii;
4704                 u8      *req_as_bytes = (u8 *) req;
4705 
4706                 /*
4707                  * Stuff request words via doorbell handshake,
4708                  * with ACK from IOC for each.
4709                  */
4710                 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4711                         u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
4712                                     (req_as_bytes[(ii*4) + 1] <<  8) |
4713                                     (req_as_bytes[(ii*4) + 2] << 16) |
4714                                     (req_as_bytes[(ii*4) + 3] << 24));
4715 
4716                         CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4717                         if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4718                                 failcnt++;
4719                 }
4720 
4721                 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4722                 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4723 
4724                 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4725                                 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4726 
4727                 /*
4728                  * Wait for completion of doorbell handshake reply from the IOC
4729                  */
4730                 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4731                         failcnt++;
4732 
4733                 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4734                                 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4735 
4736                 /*
4737                  * Copy out the cached reply...
4738                  */
4739                 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4740                         u16reply[ii] = ioc->hs_reply[ii];
4741         } else {
4742                 return -99;
4743         }
4744 
4745         return -failcnt;
4746 }
4747 
4748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4749 /**
4750  *      WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4751  *      @ioc: Pointer to MPT_ADAPTER structure
4752  *      @howlong: How long to wait (in seconds)
4753  *      @sleepFlag: Specifies whether the process can sleep
4754  *
4755  *      This routine waits (up to ~2 seconds max) for IOC doorbell
4756  *      handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4757  *      bit in its IntStatus register being clear.
4758  *
4759  *      Returns a negative value on failure, else wait loop count.
4760  */
4761 static int
4762 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4763 {
4764         int cntdn;
4765         int count = 0;
4766         u32 intstat=0;
4767 
4768         cntdn = 1000 * howlong;
4769 
4770         if (sleepFlag == CAN_SLEEP) {
4771                 while (--cntdn) {
4772                         msleep (1);
4773                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4774                         if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4775                                 break;
4776                         count++;
4777                 }
4778         } else {
4779                 while (--cntdn) {
4780                         udelay (1000);
4781                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4782                         if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4783                                 break;
4784                         count++;
4785                 }
4786         }
4787 
4788         if (cntdn) {
4789                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4790                                 ioc->name, count));
4791                 return count;
4792         }
4793 
4794         printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4795                         ioc->name, count, intstat);
4796         return -1;
4797 }
4798 
4799 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4800 /**
4801  *      WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4802  *      @ioc: Pointer to MPT_ADAPTER structure
4803  *      @howlong: How long to wait (in seconds)
4804  *      @sleepFlag: Specifies whether the process can sleep
4805  *
4806  *      This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4807  *      (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4808  *
4809  *      Returns a negative value on failure, else wait loop count.
4810  */
4811 static int
4812 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4813 {
4814         int cntdn;
4815         int count = 0;
4816         u32 intstat=0;
4817 
4818         cntdn = 1000 * howlong;
4819         if (sleepFlag == CAN_SLEEP) {
4820                 while (--cntdn) {
4821                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4822                         if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4823                                 break;
4824                         msleep(1);
4825                         count++;
4826                 }
4827         } else {
4828                 while (--cntdn) {
4829                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4830                         if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4831                                 break;
4832                         udelay (1000);
4833                         count++;
4834                 }
4835         }
4836 
4837         if (cntdn) {
4838                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4839                                 ioc->name, count, howlong));
4840                 return count;
4841         }
4842 
4843         printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4844                         ioc->name, count, intstat);
4845         return -1;
4846 }
4847 
4848 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4849 /**
4850  *      WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4851  *      @ioc: Pointer to MPT_ADAPTER structure
4852  *      @howlong: How long to wait (in seconds)
4853  *      @sleepFlag: Specifies whether the process can sleep
4854  *
4855  *      This routine polls the IOC for a handshake reply, 16 bits at a time.
4856  *      Reply is cached to IOC private area large enough to hold a maximum
4857  *      of 128 bytes of reply data.
4858  *
4859  *      Returns a negative value on failure, else size of reply in WORDS.
4860  */
4861 static int
4862 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4863 {
4864         int u16cnt = 0;
4865         int failcnt = 0;
4866         int t;
4867         u16 *hs_reply = ioc->hs_reply;
4868         volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4869         u16 hword;
4870 
4871         hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4872 
4873         /*
4874          * Get first two u16's so we can look at IOC's intended reply MsgLength
4875          */
4876         u16cnt=0;
4877         if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4878                 failcnt++;
4879         } else {
4880                 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4881                 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4882                 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4883                         failcnt++;
4884                 else {
4885                         hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4886                         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4887                 }
4888         }
4889 
4890         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4891                         ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4892                         failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4893 
4894         /*
4895          * If no error (and IOC said MsgLength is > 0), piece together
4896          * reply 16 bits at a time.
4897          */
4898         for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4899                 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4900                         failcnt++;
4901                 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4902                 /* don't overflow our IOC hs_reply[] buffer! */
4903                 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4904                         hs_reply[u16cnt] = hword;
4905                 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4906         }
4907 
4908         if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4909                 failcnt++;
4910         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4911 
4912         if (failcnt) {
4913                 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4914                                 ioc->name);
4915                 return -failcnt;
4916         }
4917 #if 0
4918         else if (u16cnt != (2 * mptReply->MsgLength)) {
4919                 return -101;
4920         }
4921         else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4922                 return -102;
4923         }
4924 #endif
4925 
4926         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4927         DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4928 
4929         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4930                         ioc->name, t, u16cnt/2));
4931         return u16cnt/2;
4932 }
4933 
4934 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4935 /**
4936  *      GetLanConfigPages - Fetch LANConfig pages.
4937  *      @ioc: Pointer to MPT_ADAPTER structure
4938  *
4939  *      Return: 0 for success
4940  *      -ENOMEM if no memory available
4941  *              -EPERM if not allowed due to ISR context
4942  *              -EAGAIN if no msg frames currently available
4943  *              -EFAULT for non-successful reply or no reply (timeout)
4944  */
4945 static int
4946 GetLanConfigPages(MPT_ADAPTER *ioc)
4947 {
4948         ConfigPageHeader_t       hdr;
4949         CONFIGPARMS              cfg;
4950         LANPage0_t              *ppage0_alloc;
4951         dma_addr_t               page0_dma;
4952         LANPage1_t              *ppage1_alloc;
4953         dma_addr_t               page1_dma;
4954         int                      rc = 0;
4955         int                      data_sz;
4956         int                      copy_sz;
4957 
4958         /* Get LAN Page 0 header */
4959         hdr.PageVersion = 0;
4960         hdr.PageLength = 0;
4961         hdr.PageNumber = 0;
4962         hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4963         cfg.cfghdr.hdr = &hdr;
4964         cfg.physAddr = -1;
4965         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4966         cfg.dir = 0;
4967         cfg.pageAddr = 0;
4968         cfg.timeout = 0;
4969 
4970         if ((rc = mpt_config(ioc, &cfg)) != 0)
4971                 return rc;
4972 
4973         if (hdr.PageLength > 0) {
4974                 data_sz = hdr.PageLength * 4;
4975                 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4976                 rc = -ENOMEM;
4977                 if (ppage0_alloc) {
4978                         memset((u8 *)ppage0_alloc, 0, data_sz);
4979                         cfg.physAddr = page0_dma;
4980                         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4981 
4982                         if ((rc = mpt_config(ioc, &cfg)) == 0) {
4983                                 /* save the data */
4984                                 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4985                                 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4986 
4987                         }
4988 
4989                         pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4990 
4991                         /* FIXME!
4992                          *      Normalize endianness of structure data,
4993                          *      by byte-swapping all > 1 byte fields!
4994                          */
4995 
4996                 }
4997 
4998                 if (rc)
4999                         return rc;
5000         }
5001 
5002         /* Get LAN Page 1 header */
5003         hdr.PageVersion = 0;
5004         hdr.PageLength = 0;
5005         hdr.PageNumber = 1;
5006         hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
5007         cfg.cfghdr.hdr = &hdr;
5008         cfg.physAddr = -1;
5009         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5010         cfg.dir = 0;
5011         cfg.pageAddr = 0;
5012 
5013         if ((rc = mpt_config(ioc, &cfg)) != 0)
5014                 return rc;
5015 
5016         if (hdr.PageLength == 0)
5017                 return 0;
5018 
5019         data_sz = hdr.PageLength * 4;
5020         rc = -ENOMEM;
5021         ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
5022         if (ppage1_alloc) {
5023                 memset((u8 *)ppage1_alloc, 0, data_sz);
5024                 cfg.physAddr = page1_dma;
5025                 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5026 
5027                 if ((rc = mpt_config(ioc, &cfg)) == 0) {
5028                         /* save the data */
5029                         copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
5030                         memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
5031                 }
5032 
5033                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
5034 
5035                 /* FIXME!
5036                  *      Normalize endianness of structure data,
5037                  *      by byte-swapping all > 1 byte fields!
5038                  */
5039 
5040         }
5041 
5042         return rc;
5043 }
5044 
5045 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5046 /**
5047  *      mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5048  *      @ioc: Pointer to MPT_ADAPTER structure
5049  *      @persist_opcode: see below
5050  *
5051  *      MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5052  *              devices not currently present.
5053  *      MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5054  *
5055  *      NOTE: Don't use not this function during interrupt time.
5056  *
5057  *      Returns 0 for success, non-zero error
5058  */
5059 
5060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5061 int
5062 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5063 {
5064         SasIoUnitControlRequest_t       *sasIoUnitCntrReq;
5065         SasIoUnitControlReply_t         *sasIoUnitCntrReply;
5066         MPT_FRAME_HDR                   *mf = NULL;
5067         MPIHeader_t                     *mpi_hdr;
5068         int                             ret = 0;
5069         unsigned long                   timeleft;
5070 
5071         mutex_lock(&ioc->mptbase_cmds.mutex);
5072 
5073         /* init the internal cmd struct */
5074         memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5075         INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5076 
5077         /* insure garbage is not sent to fw */
5078         switch(persist_opcode) {
5079 
5080         case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5081         case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5082                 break;
5083 
5084         default:
5085                 ret = -1;
5086                 goto out;
5087         }
5088 
5089         printk(KERN_DEBUG  "%s: persist_opcode=%x\n",
5090                 __func__, persist_opcode);
5091 
5092         /* Get a MF for this command.
5093          */
5094         if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5095                 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5096                 ret = -1;
5097                 goto out;
5098         }
5099 
5100         mpi_hdr = (MPIHeader_t *) mf;
5101         sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5102         memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5103         sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5104         sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5105         sasIoUnitCntrReq->Operation = persist_opcode;
5106 
5107         mpt_put_msg_frame(mpt_base_index, ioc, mf);
5108         timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5109         if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5110                 ret = -ETIME;
5111                 printk(KERN_DEBUG "%s: failed\n", __func__);
5112                 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5113                         goto out;
5114                 if (!timeleft) {
5115                         printk(MYIOC_s_WARN_FMT
5116                                "Issuing Reset from %s!!, doorbell=0x%08x\n",
5117                                ioc->name, __func__, mpt_GetIocState(ioc, 0));
5118                         mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5119                         mpt_free_msg_frame(ioc, mf);
5120                 }
5121                 goto out;
5122         }
5123 
5124         if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5125                 ret = -1;
5126                 goto out;
5127         }
5128 
5129         sasIoUnitCntrReply =
5130             (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5131         if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5132                 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5133                     __func__, sasIoUnitCntrReply->IOCStatus,
5134                     sasIoUnitCntrReply->IOCLogInfo);
5135                 printk(KERN_DEBUG "%s: failed\n", __func__);
5136                 ret = -1;
5137         } else
5138                 printk(KERN_DEBUG "%s: success\n", __func__);
5139  out:
5140 
5141         CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5142         mutex_unlock(&ioc->mptbase_cmds.mutex);
5143         return ret;
5144 }
5145 
5146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5147 
5148 static void
5149 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5150     MpiEventDataRaid_t * pRaidEventData)
5151 {
5152         int     volume;
5153         int     reason;
5154         int     disk;
5155         int     status;
5156         int     flags;
5157         int     state;
5158 
5159         volume  = pRaidEventData->VolumeID;
5160         reason  = pRaidEventData->ReasonCode;
5161         disk    = pRaidEventData->PhysDiskNum;
5162         status  = le32_to_cpu(pRaidEventData->SettingsStatus);
5163         flags   = (status >> 0) & 0xff;
5164         state   = (status >> 8) & 0xff;
5165 
5166         if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5167                 return;
5168         }
5169 
5170         if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5171              reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5172             (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5173                 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5174                         ioc->name, disk, volume);
5175         } else {
5176                 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5177                         ioc->name, volume);
5178         }
5179 
5180         switch(reason) {
5181         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5182                 printk(MYIOC_s_INFO_FMT "  volume has been created\n",
5183                         ioc->name);
5184                 break;
5185 
5186         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5187 
5188                 printk(MYIOC_s_INFO_FMT "  volume has been deleted\n",
5189                         ioc->name);
5190                 break;
5191 
5192         case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5193                 printk(MYIOC_s_INFO_FMT "  volume settings have been changed\n",
5194                         ioc->name);
5195                 break;
5196 
5197         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5198                 printk(MYIOC_s_INFO_FMT "  volume is now %s%s%s%s\n",
5199                         ioc->name,
5200                         state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5201                          ? "optimal"
5202                          : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5203                           ? "degraded"
5204                           : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5205                            ? "failed"
5206                            : "state unknown",
5207                         flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5208                          ? ", enabled" : "",
5209                         flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5210                          ? ", quiesced" : "",
5211                         flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5212                          ? ", resync in progress" : "" );
5213                 break;
5214 
5215         case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5216                 printk(MYIOC_s_INFO_FMT "  volume membership of PhysDisk %d has changed\n",
5217                         ioc->name, disk);
5218                 break;
5219 
5220         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5221                 printk(MYIOC_s_INFO_FMT "  PhysDisk has been created\n",
5222                         ioc->name);
5223                 break;
5224 
5225         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5226                 printk(MYIOC_s_INFO_FMT "  PhysDisk has been deleted\n",
5227                         ioc->name);
5228                 break;
5229 
5230         case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5231                 printk(MYIOC_s_INFO_FMT "  PhysDisk settings have been changed\n",
5232                         ioc->name);
5233                 break;
5234 
5235         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5236                 printk(MYIOC_s_INFO_FMT "  PhysDisk is now %s%s%s\n",
5237                         ioc->name,
5238                         state == MPI_PHYSDISK0_STATUS_ONLINE
5239                          ? "online"
5240                          : state == MPI_PHYSDISK0_STATUS_MISSING
5241                           ? "missing"
5242                           : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5243                            ? "not compatible"
5244                            : state == MPI_PHYSDISK0_STATUS_FAILED
5245                             ? "failed"
5246                             : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5247                              ? "initializing"
5248                              : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5249                               ? "offline requested"
5250                               : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5251                                ? "failed requested"
5252                                : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5253                                 ? "offline"
5254                                 : "state unknown",
5255                         flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5256                          ? ", out of sync" : "",
5257                         flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5258                          ? ", quiesced" : "" );
5259                 break;
5260 
5261         case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5262                 printk(MYIOC_s_INFO_FMT "  Domain Validation needed for PhysDisk %d\n",
5263                         ioc->name, disk);
5264                 break;
5265 
5266         case MPI_EVENT_RAID_RC_SMART_DATA:
5267                 printk(MYIOC_s_INFO_FMT "  SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5268                         ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5269                 break;
5270 
5271         case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5272                 printk(MYIOC_s_INFO_FMT "  replacement of PhysDisk %d has started\n",
5273                         ioc->name, disk);
5274                 break;
5275         }
5276 }
5277 
5278 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5279 /**
5280  *      GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5281  *      @ioc: Pointer to MPT_ADAPTER structure
5282  *
5283  *      Returns: 0 for success
5284  *      -ENOMEM if no memory available
5285  *              -EPERM if not allowed due to ISR context
5286  *              -EAGAIN if no msg frames currently available
5287  *              -EFAULT for non-successful reply or no reply (timeout)
5288  */
5289 static int
5290 GetIoUnitPage2(MPT_ADAPTER *ioc)
5291 {
5292         ConfigPageHeader_t       hdr;
5293         CONFIGPARMS              cfg;
5294         IOUnitPage2_t           *ppage_alloc;
5295         dma_addr_t               page_dma;
5296         int                      data_sz;
5297         int                      rc;
5298 
5299         /* Get the page header */
5300         hdr.PageVersion = 0;
5301         hdr.PageLength = 0;
5302         hdr.PageNumber = 2;
5303         hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5304         cfg.cfghdr.hdr = &hdr;
5305         cfg.physAddr = -1;
5306         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5307         cfg.dir = 0;
5308         cfg.pageAddr = 0;
5309         cfg.timeout = 0;
5310 
5311         if ((rc = mpt_config(ioc, &cfg)) != 0)
5312                 return rc;
5313 
5314         if (hdr.PageLength == 0)
5315                 return 0;
5316 
5317         /* Read the config page */
5318         data_sz = hdr.PageLength * 4;
5319         rc = -ENOMEM;
5320         ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5321         if (ppage_alloc) {
5322                 memset((u8 *)ppage_alloc, 0, data_sz);
5323                 cfg.physAddr = page_dma;
5324                 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5325 
5326                 /* If Good, save data */
5327                 if ((rc = mpt_config(ioc, &cfg)) == 0)
5328                         ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5329 
5330                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5331         }
5332 
5333         return rc;
5334 }
5335 
5336 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5337 /**
5338  *      mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5339  *      @ioc: Pointer to a Adapter Strucutre
5340  *      @portnum: IOC port number
5341  *
5342  *      Return: -EFAULT if read of config page header fails
5343  *                      or if no nvram
5344  *      If read of SCSI Port Page 0 fails,
5345  *              NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
5346  *              Adapter settings: async, narrow
5347  *              Return 1
5348  *      If read of SCSI Port Page 2 fails,
5349  *              Adapter settings valid
5350  *              NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
5351  *              Return 1
5352  *      Else
5353  *              Both valid
5354  *              Return 0
5355  *      CHECK - what type of locking mechanisms should be used????
5356  */
5357 static int
5358 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5359 {
5360         u8                      *pbuf;
5361         dma_addr_t               buf_dma;
5362         CONFIGPARMS              cfg;
5363         ConfigPageHeader_t       header;
5364         int                      ii;
5365         int                      data, rc = 0;
5366 
5367         /* Allocate memory
5368          */
5369         if (!ioc->spi_data.nvram) {
5370                 int      sz;
5371                 u8      *mem;
5372                 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5373                 mem = kmalloc(sz, GFP_ATOMIC);
5374                 if (mem == NULL)
5375                         return -EFAULT;
5376 
5377                 ioc->spi_data.nvram = (int *) mem;
5378 
5379                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5380                         ioc->name, ioc->spi_data.nvram, sz));
5381         }
5382 
5383         /* Invalidate NVRAM information
5384          */
5385         for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5386                 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5387         }
5388 
5389         /* Read SPP0 header, allocate memory, then read page.
5390          */
5391         header.PageVersion = 0;
5392         header.PageLength = 0;
5393         header.PageNumber = 0;
5394         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5395         cfg.cfghdr.hdr = &header;
5396         cfg.physAddr = -1;
5397         cfg.pageAddr = portnum;
5398         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5399         cfg.dir = 0;
5400         cfg.timeout = 0;        /* use default */
5401         if (mpt_config(ioc, &cfg) != 0)
5402                  return -EFAULT;
5403 
5404         if (header.PageLength > 0) {
5405                 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5406                 if (pbuf) {
5407                         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5408                         cfg.physAddr = buf_dma;
5409                         if (mpt_config(ioc, &cfg) != 0) {
5410                                 ioc->spi_data.maxBusWidth = MPT_NARROW;
5411                                 ioc->spi_data.maxSyncOffset = 0;
5412                                 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5413                                 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5414                                 rc = 1;
5415                                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5416                                         "Unable to read PortPage0 minSyncFactor=%x\n",
5417                                         ioc->name, ioc->spi_data.minSyncFactor));
5418                         } else {
5419                                 /* Save the Port Page 0 data
5420                                  */
5421                                 SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
5422                                 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5423                                 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5424 
5425                                 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5426                                         ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5427                                         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5428                                                 "noQas due to Capabilities=%x\n",
5429                                                 ioc->name, pPP0->Capabilities));
5430                                 }
5431                                 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5432                                 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5433                                 if (data) {
5434                                         ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5435                                         data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5436                                         ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5437                                         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5438                                                 "PortPage0 minSyncFactor=%x\n",
5439                                                 ioc->name, ioc->spi_data.minSyncFactor));
5440                                 } else {
5441                                         ioc->spi_data.maxSyncOffset = 0;
5442                                         ioc->spi_data.minSyncFactor = MPT_ASYNC;
5443                                 }
5444 
5445                                 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5446 
5447                                 /* Update the minSyncFactor based on bus type.
5448                                  */
5449                                 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5450                                         (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
5451 
5452                                         if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5453                                                 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5454                                                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5455                                                         "HVD or SE detected, minSyncFactor=%x\n",
5456                                                         ioc->name, ioc->spi_data.minSyncFactor));
5457                                         }
5458                                 }
5459                         }
5460                         if (pbuf) {
5461                                 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5462                         }
5463                 }
5464         }
5465 
5466         /* SCSI Port Page 2 - Read the header then the page.
5467          */
5468         header.PageVersion = 0;
5469         header.PageLength = 0;
5470         header.PageNumber = 2;
5471         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5472         cfg.cfghdr.hdr = &header;
5473         cfg.physAddr = -1;
5474         cfg.pageAddr = portnum;
5475         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5476         cfg.dir = 0;
5477         if (mpt_config(ioc, &cfg) != 0)
5478                 return -EFAULT;
5479 
5480         if (header.PageLength > 0) {
5481                 /* Allocate memory and read SCSI Port Page 2
5482                  */
5483                 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5484                 if (pbuf) {
5485                         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5486                         cfg.physAddr = buf_dma;
5487                         if (mpt_config(ioc, &cfg) != 0) {
5488                                 /* Nvram data is left with INVALID mark
5489                                  */
5490                                 rc = 1;
5491                         } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5492 
5493                                 /* This is an ATTO adapter, read Page2 accordingly
5494                                 */
5495                                 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t  *) pbuf;
5496                                 ATTODeviceInfo_t *pdevice = NULL;
5497                                 u16 ATTOFlags;
5498 
5499                                 /* Save the Port Page 2 data
5500                                  * (reformat into a 32bit quantity)
5501                                  */
5502                                 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5503                                   pdevice = &pPP2->DeviceSettings[ii];
5504                                   ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5505                                   data = 0;
5506 
5507                                   /* Translate ATTO device flags to LSI format
5508                                    */
5509                                   if (ATTOFlags & ATTOFLAG_DISC)
5510                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5511                                   if (ATTOFlags & ATTOFLAG_ID_ENB)
5512                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5513                                   if (ATTOFlags & ATTOFLAG_LUN_ENB)
5514                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5515                                   if (ATTOFlags & ATTOFLAG_TAGGED)
5516                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5517                                   if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5518                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5519 
5520                                   data = (data << 16) | (pdevice->Period << 8) | 10;
5521                                   ioc->spi_data.nvram[ii] = data;
5522                                 }
5523                         } else {
5524                                 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
5525                                 MpiDeviceInfo_t *pdevice = NULL;
5526 
5527                                 /*
5528                                  * Save "Set to Avoid SCSI Bus Resets" flag
5529                                  */
5530                                 ioc->spi_data.bus_reset =
5531                                     (le32_to_cpu(pPP2->PortFlags) &
5532                                 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5533                                     0 : 1 ;
5534 
5535                                 /* Save the Port Page 2 data
5536                                  * (reformat into a 32bit quantity)
5537                                  */
5538                                 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5539                                 ioc->spi_data.PortFlags = data;
5540                                 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5541                                         pdevice = &pPP2->DeviceSettings[ii];
5542                                         data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5543                                                 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5544                                         ioc->spi_data.nvram[ii] = data;
5545                                 }
5546                         }
5547 
5548                         pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5549                 }
5550         }
5551 
5552         /* Update Adapter limits with those from NVRAM
5553          * Comment: Don't need to do this. Target performance
5554          * parameters will never exceed the adapters limits.
5555          */
5556 
5557         return rc;
5558 }
5559 
5560 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5561 /**
5562  *      mpt_readScsiDevicePageHeaders - save version and length of SDP1
5563  *      @ioc: Pointer to a Adapter Strucutre
5564  *      @portnum: IOC port number
5565  *
5566  *      Return: -EFAULT if read of config page header fails
5567  *              or 0 if success.
5568  */
5569 static int
5570 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5571 {
5572         CONFIGPARMS              cfg;
5573         ConfigPageHeader_t       header;
5574 
5575         /* Read the SCSI Device Page 1 header
5576          */
5577         header.PageVersion = 0;
5578         header.PageLength = 0;
5579         header.PageNumber = 1;
5580         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5581         cfg.cfghdr.hdr = &header;
5582         cfg.physAddr = -1;
5583         cfg.pageAddr = portnum;
5584         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5585         cfg.dir = 0;
5586         cfg.timeout = 0;
5587         if (mpt_config(ioc, &cfg) != 0)
5588                  return -EFAULT;
5589 
5590         ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5591         ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5592 
5593         header.PageVersion = 0;
5594         header.PageLength = 0;
5595         header.PageNumber = 0;
5596         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5597         if (mpt_config(ioc, &cfg) != 0)
5598                  return -EFAULT;
5599 
5600         ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5601         ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5602 
5603         dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5604                         ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5605 
5606         dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5607                         ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5608         return 0;
5609 }
5610 
5611 /**
5612  * mpt_inactive_raid_list_free - This clears this link list.
5613  * @ioc : pointer to per adapter structure
5614  **/
5615 static void
5616 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5617 {
5618         struct inactive_raid_component_info *component_info, *pNext;
5619 
5620         if (list_empty(&ioc->raid_data.inactive_list))
5621                 return;
5622 
5623         mutex_lock(&ioc->raid_data.inactive_list_mutex);
5624         list_for_each_entry_safe(component_info, pNext,
5625             &ioc->raid_data.inactive_list, list) {
5626                 list_del(&component_info->list);
5627                 kfree(component_info);
5628         }
5629         mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5630 }
5631 
5632 /**
5633  * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5634  *
5635  * @ioc : pointer to per adapter structure
5636  * @channel : volume channel
5637  * @id : volume target id
5638  **/
5639 static void
5640 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5641 {
5642         CONFIGPARMS                     cfg;
5643         ConfigPageHeader_t              hdr;
5644         dma_addr_t                      dma_handle;
5645         pRaidVolumePage0_t              buffer = NULL;
5646         int                             i;
5647         RaidPhysDiskPage0_t             phys_disk;
5648         struct inactive_raid_component_info *component_info;
5649         int                             handle_inactive_volumes;
5650 
5651         memset(&cfg, 0 , sizeof(CONFIGPARMS));
5652         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5653         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5654         cfg.pageAddr = (channel << 8) + id;
5655         cfg.cfghdr.hdr = &hdr;
5656         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5657 
5658         if (mpt_config(ioc, &cfg) != 0)
5659                 goto out;
5660 
5661         if (!hdr.PageLength)
5662                 goto out;
5663 
5664         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5665             &dma_handle);
5666 
5667         if (!buffer)
5668                 goto out;
5669 
5670         cfg.physAddr = dma_handle;
5671         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5672 
5673         if (mpt_config(ioc, &cfg) != 0)
5674                 goto out;
5675 
5676         if (!buffer->NumPhysDisks)
5677                 goto out;
5678 
5679         handle_inactive_volumes =
5680            (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5681            (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5682             buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5683             buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5684 
5685         if (!handle_inactive_volumes)
5686                 goto out;
5687 
5688         mutex_lock(&ioc->raid_data.inactive_list_mutex);
5689         for (i = 0; i < buffer->NumPhysDisks; i++) {
5690                 if(mpt_raid_phys_disk_pg0(ioc,
5691                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5692                         continue;
5693 
5694                 if ((component_info = kmalloc(sizeof (*component_info),
5695                  GFP_KERNEL)) == NULL)
5696                         continue;
5697 
5698                 component_info->volumeID = id;
5699                 component_info->volumeBus = channel;
5700                 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5701                 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5702                 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5703                 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5704 
5705                 list_add_tail(&component_info->list,
5706                     &ioc->raid_data.inactive_list);
5707         }
5708         mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5709 
5710  out:
5711         if (buffer)
5712                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5713                     dma_handle);
5714 }
5715 
5716 /**
5717  *      mpt_raid_phys_disk_pg0 - returns phys disk page zero
5718  *      @ioc: Pointer to a Adapter Structure
5719  *      @phys_disk_num: io unit unique phys disk num generated by the ioc
5720  *      @phys_disk: requested payload data returned
5721  *
5722  *      Return:
5723  *      0 on success
5724  *      -EFAULT if read of config page header fails or data pointer not NULL
5725  *      -ENOMEM if pci_alloc failed
5726  **/
5727 int
5728 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5729                         RaidPhysDiskPage0_t *phys_disk)
5730 {
5731         CONFIGPARMS                     cfg;
5732         ConfigPageHeader_t              hdr;
5733         dma_addr_t                      dma_handle;
5734         pRaidPhysDiskPage0_t            buffer = NULL;
5735         int                             rc;
5736 
5737         memset(&cfg, 0 , sizeof(CONFIGPARMS));
5738         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5739         memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5740 
5741         hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5742         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5743         cfg.cfghdr.hdr = &hdr;
5744         cfg.physAddr = -1;
5745         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5746 
5747         if (mpt_config(ioc, &cfg) != 0) {
5748                 rc = -EFAULT;
5749                 goto out;
5750         }
5751 
5752         if (!hdr.PageLength) {
5753                 rc = -EFAULT;
5754                 goto out;
5755         }
5756 
5757         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5758             &dma_handle);
5759 
5760         if (!buffer) {
5761                 rc = -ENOMEM;
5762                 goto out;
5763         }
5764 
5765         cfg.physAddr = dma_handle;
5766         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5767         cfg.pageAddr = phys_disk_num;
5768 
5769         if (mpt_config(ioc, &cfg) != 0) {
5770                 rc = -EFAULT;
5771                 goto out;
5772         }
5773 
5774         rc = 0;
5775         memcpy(phys_disk, buffer, sizeof(*buffer));
5776         phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5777 
5778  out:
5779 
5780         if (buffer)
5781                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5782                     dma_handle);
5783 
5784         return rc;
5785 }
5786 
5787 /**
5788  *      mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5789  *      @ioc: Pointer to a Adapter Structure
5790  *      @phys_disk_num: io unit unique phys disk num generated by the ioc
5791  *
5792  *      Return:
5793  *      returns number paths
5794  **/
5795 int
5796 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5797 {
5798         CONFIGPARMS                     cfg;
5799         ConfigPageHeader_t              hdr;
5800         dma_addr_t                      dma_handle;
5801         pRaidPhysDiskPage1_t            buffer = NULL;
5802         int                             rc;
5803 
5804         memset(&cfg, 0 , sizeof(CONFIGPARMS));
5805         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5806 
5807         hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5808         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5809         hdr.PageNumber = 1;
5810         cfg.cfghdr.hdr = &hdr;
5811         cfg.physAddr = -1;
5812         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5813 
5814         if (mpt_config(ioc, &cfg) != 0) {
5815                 rc = 0;
5816                 goto out;
5817         }
5818 
5819         if (!hdr.PageLength) {
5820                 rc = 0;
5821                 goto out;
5822         }
5823 
5824         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5825             &dma_handle);
5826 
5827         if (!buffer) {
5828                 rc = 0;
5829                 goto out;
5830         }
5831 
5832         cfg.physAddr = dma_handle;
5833         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5834         cfg.pageAddr = phys_disk_num;
5835 
5836         if (mpt_config(ioc, &cfg) != 0) {
5837                 rc = 0;
5838                 goto out;
5839         }
5840 
5841         rc = buffer->NumPhysDiskPaths;
5842  out:
5843 
5844         if (buffer)
5845                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5846                     dma_handle);
5847 
5848         return rc;
5849 }
5850 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5851 
5852 /**
5853  *      mpt_raid_phys_disk_pg1 - returns phys disk page 1
5854  *      @ioc: Pointer to a Adapter Structure
5855  *      @phys_disk_num: io unit unique phys disk num generated by the ioc
5856  *      @phys_disk: requested payload data returned
5857  *
5858  *      Return:
5859  *      0 on success
5860  *      -EFAULT if read of config page header fails or data pointer not NULL
5861  *      -ENOMEM if pci_alloc failed
5862  **/
5863 int
5864 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5865                 RaidPhysDiskPage1_t *phys_disk)
5866 {
5867         CONFIGPARMS                     cfg;
5868         ConfigPageHeader_t              hdr;
5869         dma_addr_t                      dma_handle;
5870         pRaidPhysDiskPage1_t            buffer = NULL;
5871         int                             rc;
5872         int                             i;
5873         __le64                          sas_address;
5874 
5875         memset(&cfg, 0 , sizeof(CONFIGPARMS));
5876         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5877         rc = 0;
5878 
5879         hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5880         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5881         hdr.PageNumber = 1;
5882         cfg.cfghdr.hdr = &hdr;
5883         cfg.physAddr = -1;
5884         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5885 
5886         if (mpt_config(ioc, &cfg) != 0) {
5887                 rc = -EFAULT;
5888                 goto out;
5889         }
5890 
5891         if (!hdr.PageLength) {
5892                 rc = -EFAULT;
5893                 goto out;
5894         }
5895 
5896         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5897             &dma_handle);
5898 
5899         if (!buffer) {
5900                 rc = -ENOMEM;
5901                 goto out;
5902         }
5903 
5904         cfg.physAddr = dma_handle;
5905         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5906         cfg.pageAddr = phys_disk_num;
5907 
5908         if (mpt_config(ioc, &cfg) != 0) {
5909                 rc = -EFAULT;
5910                 goto out;
5911         }
5912 
5913         phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5914         phys_disk->PhysDiskNum = phys_disk_num;
5915         for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5916                 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5917                 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5918                 phys_disk->Path[i].OwnerIdentifier =
5919                                 buffer->Path[i].OwnerIdentifier;
5920                 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5921                 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5922                 sas_address = le64_to_cpu(sas_address);
5923                 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5924                 memcpy(&sas_address,
5925                                 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5926                 sas_address = le64_to_cpu(sas_address);
5927                 memcpy(&phys_disk->Path[i].OwnerWWID,
5928                                 &sas_address, sizeof(__le64));
5929         }
5930 
5931  out:
5932 
5933         if (buffer)
5934                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5935                     dma_handle);
5936 
5937         return rc;
5938 }
5939 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5940 
5941 
5942 /**
5943  *      mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5944  *      @ioc: Pointer to a Adapter Strucutre
5945  *
5946  *      Return:
5947  *      0 on success
5948  *      -EFAULT if read of config page header fails or data pointer not NULL
5949  *      -ENOMEM if pci_alloc failed
5950  **/
5951 int
5952 mpt_findImVolumes(MPT_ADAPTER *ioc)
5953 {
5954         IOCPage2_t              *pIoc2;
5955         u8                      *mem;
5956         dma_addr_t               ioc2_dma;
5957         CONFIGPARMS              cfg;
5958         ConfigPageHeader_t       header;
5959         int                      rc = 0;
5960         int                      iocpage2sz;
5961         int                      i;
5962 
5963         if (!ioc->ir_firmware)
5964                 return 0;
5965 
5966         /* Free the old page
5967          */
5968         kfree(ioc->raid_data.pIocPg2);
5969         ioc->raid_data.pIocPg2 = NULL;
5970         mpt_inactive_raid_list_free(ioc);
5971 
5972         /* Read IOCP2 header then the page.
5973          */
5974         header.PageVersion = 0;
5975         header.PageLength = 0;
5976         header.PageNumber = 2;
5977         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5978         cfg.cfghdr.hdr = &header;
5979         cfg.physAddr = -1;
5980         cfg.pageAddr = 0;
5981         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5982         cfg.dir = 0;
5983         cfg.timeout = 0;
5984         if (mpt_config(ioc, &cfg) != 0)
5985                  return -EFAULT;
5986 
5987         if (header.PageLength == 0)
5988                 return -EFAULT;
5989 
5990         iocpage2sz = header.PageLength * 4;
5991         pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5992         if (!pIoc2)
5993                 return -ENOMEM;
5994 
5995         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5996         cfg.physAddr = ioc2_dma;
5997         if (mpt_config(ioc, &cfg) != 0)
5998                 goto out;
5999 
6000         mem = kmalloc(iocpage2sz, GFP_KERNEL);
6001         if (!mem) {
6002                 rc = -ENOMEM;
6003                 goto out;
6004         }
6005 
6006         memcpy(mem, (u8 *)pIoc2, iocpage2sz);
6007         ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
6008 
6009         mpt_read_ioc_pg_3(ioc);
6010 
6011         for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
6012                 mpt_inactive_raid_volumes(ioc,
6013                     pIoc2->RaidVolume[i].VolumeBus,
6014                     pIoc2->RaidVolume[i].VolumeID);
6015 
6016  out:
6017         pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
6018 
6019         return rc;
6020 }
6021 
6022 static int
6023 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
6024 {
6025         IOCPage3_t              *pIoc3;
6026         u8                      *mem;
6027         CONFIGPARMS              cfg;
6028         ConfigPageHeader_t       header;
6029         dma_addr_t               ioc3_dma;
6030         int                      iocpage3sz = 0;
6031 
6032         /* Free the old page
6033          */
6034         kfree(ioc->raid_data.pIocPg3);
6035         ioc->raid_data.pIocPg3 = NULL;
6036 
6037         /* There is at least one physical disk.
6038          * Read and save IOC Page 3
6039          */
6040         header.PageVersion = 0;
6041         header.PageLength = 0;
6042         header.PageNumber = 3;
6043         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6044         cfg.cfghdr.hdr = &header;
6045         cfg.physAddr = -1;
6046         cfg.pageAddr = 0;
6047         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6048         cfg.dir = 0;
6049         cfg.timeout = 0;
6050         if (mpt_config(ioc, &cfg) != 0)
6051                 return 0;
6052 
6053         if (header.PageLength == 0)
6054                 return 0;
6055 
6056         /* Read Header good, alloc memory
6057          */
6058         iocpage3sz = header.PageLength * 4;
6059         pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6060         if (!pIoc3)
6061                 return 0;
6062 
6063         /* Read the Page and save the data
6064          * into malloc'd memory.
6065          */
6066         cfg.physAddr = ioc3_dma;
6067         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6068         if (mpt_config(ioc, &cfg) == 0) {
6069                 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6070                 if (mem) {
6071                         memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6072                         ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6073                 }
6074         }
6075 
6076         pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6077 
6078         return 0;
6079 }
6080 
6081 static void
6082 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6083 {
6084         IOCPage4_t              *pIoc4;
6085         CONFIGPARMS              cfg;
6086         ConfigPageHeader_t       header;
6087         dma_addr_t               ioc4_dma;
6088         int                      iocpage4sz;
6089 
6090         /* Read and save IOC Page 4
6091          */
6092         header.PageVersion = 0;
6093         header.PageLength = 0;
6094         header.PageNumber = 4;
6095         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6096         cfg.cfghdr.hdr = &header;
6097         cfg.physAddr = -1;
6098         cfg.pageAddr = 0;
6099         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6100         cfg.dir = 0;
6101         cfg.timeout = 0;
6102         if (mpt_config(ioc, &cfg) != 0)
6103                 return;
6104 
6105         if (header.PageLength == 0)
6106                 return;
6107 
6108         if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6109                 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6110                 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6111                 if (!pIoc4)
6112                         return;
6113                 ioc->alloc_total += iocpage4sz;
6114         } else {
6115                 ioc4_dma = ioc->spi_data.IocPg4_dma;
6116                 iocpage4sz = ioc->spi_data.IocPg4Sz;
6117         }
6118 
6119         /* Read the Page into dma memory.
6120          */
6121         cfg.physAddr = ioc4_dma;
6122         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6123         if (mpt_config(ioc, &cfg) == 0) {
6124                 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6125                 ioc->spi_data.IocPg4_dma = ioc4_dma;
6126                 ioc->spi_data.IocPg4Sz = iocpage4sz;
6127         } else {
6128                 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6129                 ioc->spi_data.pIocPg4 = NULL;
6130                 ioc->alloc_total -= iocpage4sz;
6131         }
6132 }
6133 
6134 static void
6135 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6136 {
6137         IOCPage1_t              *pIoc1;
6138         CONFIGPARMS              cfg;
6139         ConfigPageHeader_t       header;
6140         dma_addr_t               ioc1_dma;
6141         int                      iocpage1sz = 0;
6142         u32                      tmp;
6143 
6144         /* Check the Coalescing Timeout in IOC Page 1
6145          */
6146         header.PageVersion = 0;
6147         header.PageLength = 0;
6148         header.PageNumber = 1;
6149         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6150         cfg.cfghdr.hdr = &header;
6151         cfg.physAddr = -1;
6152         cfg.pageAddr = 0;
6153         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6154         cfg.dir = 0;
6155         cfg.timeout = 0;
6156         if (mpt_config(ioc, &cfg) != 0)
6157                 return;
6158 
6159         if (header.PageLength == 0)
6160                 return;
6161 
6162         /* Read Header good, alloc memory
6163          */
6164         iocpage1sz = header.PageLength * 4;
6165         pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6166         if (!pIoc1)
6167                 return;
6168 
6169         /* Read the Page and check coalescing timeout
6170          */
6171         cfg.physAddr = ioc1_dma;
6172         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6173         if (mpt_config(ioc, &cfg) == 0) {
6174 
6175                 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6176                 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6177                         tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6178 
6179                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6180                                         ioc->name, tmp));
6181 
6182                         if (tmp > MPT_COALESCING_TIMEOUT) {
6183                                 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6184 
6185                                 /* Write NVRAM and current
6186                                  */
6187                                 cfg.dir = 1;
6188                                 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6189                                 if (mpt_config(ioc, &cfg) == 0) {
6190                                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6191                                                         ioc->name, MPT_COALESCING_TIMEOUT));
6192 
6193                                         cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6194                                         if (mpt_config(ioc, &cfg) == 0) {
6195                                                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6196                                                                 "Reset NVRAM Coalescing Timeout to = %d\n",
6197                                                                 ioc->name, MPT_COALESCING_TIMEOUT));
6198                                         } else {
6199                                                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6200                                                                 "Reset NVRAM Coalescing Timeout Failed\n",
6201                                                                 ioc->name));
6202                                         }
6203 
6204                                 } else {
6205                                         dprintk(ioc, printk(MYIOC_s_WARN_FMT
6206                                                 "Reset of Current Coalescing Timeout Failed!\n",
6207                                                 ioc->name));
6208                                 }
6209                         }
6210 
6211                 } else {
6212                         dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6213                 }
6214         }
6215 
6216         pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6217 
6218         return;
6219 }
6220 
6221 static void
6222 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6223 {
6224         CONFIGPARMS             cfg;
6225         ConfigPageHeader_t      hdr;
6226         dma_addr_t              buf_dma;
6227         ManufacturingPage0_t    *pbuf = NULL;
6228 
6229         memset(&cfg, 0 , sizeof(CONFIGPARMS));
6230         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6231 
6232         hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6233         cfg.cfghdr.hdr = &hdr;
6234         cfg.physAddr = -1;
6235         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6236         cfg.timeout = 10;
6237 
6238         if (mpt_config(ioc, &cfg) != 0)
6239                 goto out;
6240 
6241         if (!cfg.cfghdr.hdr->PageLength)
6242                 goto out;
6243 
6244         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6245         pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6246         if (!pbuf)
6247                 goto out;
6248 
6249         cfg.physAddr = buf_dma;
6250 
6251         if (mpt_config(ioc, &cfg) != 0)
6252                 goto out;
6253 
6254         memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6255         memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6256         memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6257 
6258 out:
6259 
6260         if (pbuf)
6261                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6262 }
6263 
6264 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6265 /**
6266  *      SendEventNotification - Send EventNotification (on or off) request to adapter
6267  *      @ioc: Pointer to MPT_ADAPTER structure
6268  *      @EvSwitch: Event switch flags
6269  *      @sleepFlag: Specifies whether the process can sleep
6270  */
6271 static int
6272 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6273 {
6274         EventNotification_t     evn;
6275         MPIDefaultReply_t       reply_buf;
6276 
6277         memset(&evn, 0, sizeof(EventNotification_t));
6278         memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6279 
6280         evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6281         evn.Switch = EvSwitch;
6282         evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6283 
6284         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6285             "Sending EventNotification (%d) request %p\n",
6286             ioc->name, EvSwitch, &evn));
6287 
6288         return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6289             (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6290             sleepFlag);
6291 }
6292 
6293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6294 /**
6295  *      SendEventAck - Send EventAck request to MPT adapter.
6296  *      @ioc: Pointer to MPT_ADAPTER structure
6297  *      @evnp: Pointer to original EventNotification request
6298  */
6299 static int
6300 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6301 {
6302         EventAck_t      *pAck;
6303 
6304         if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6305                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6306                     ioc->name, __func__));
6307                 return -1;
6308         }
6309 
6310         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6311 
6312         pAck->Function     = MPI_FUNCTION_EVENT_ACK;
6313         pAck->ChainOffset  = 0;
6314         pAck->Reserved[0]  = pAck->Reserved[1] = 0;
6315         pAck->MsgFlags     = 0;
6316         pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6317         pAck->Event        = evnp->Event;
6318         pAck->EventContext = evnp->EventContext;
6319 
6320         mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6321 
6322         return 0;
6323 }
6324 
6325 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6326 /**
6327  *      mpt_config - Generic function to issue config message
6328  *      @ioc:   Pointer to an adapter structure
6329  *      @pCfg:  Pointer to a configuration structure. Struct contains
6330  *              action, page address, direction, physical address
6331  *              and pointer to a configuration page header
6332  *              Page header is updated.
6333  *
6334  *      Returns 0 for success
6335  *      -EPERM if not allowed due to ISR context
6336  *      -EAGAIN if no msg frames currently available
6337  *      -EFAULT for non-successful reply or no reply (timeout)
6338  */
6339 int
6340 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6341 {
6342         Config_t        *pReq;
6343         ConfigReply_t   *pReply;
6344         ConfigExtendedPageHeader_t  *pExtHdr = NULL;
6345         MPT_FRAME_HDR   *mf;
6346         int              ii;
6347         int              flagsLength;
6348         long             timeout;
6349         int              ret;
6350         u8               page_type = 0, extend_page;
6351         unsigned long    timeleft;
6352         unsigned long    flags;
6353     int          in_isr;
6354         u8               issue_hard_reset = 0;
6355         u8               retry_count = 0;
6356 
6357         /*      Prevent calling wait_event() (below), if caller happens
6358          *      to be in ISR context, because that is fatal!
6359          */
6360         in_isr = in_interrupt();
6361         if (in_isr) {
6362                 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6363                                 ioc->name));
6364                 return -EPERM;
6365     }
6366 
6367         /* don't send a config page during diag reset */
6368         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6369         if (ioc->ioc_reset_in_progress) {
6370                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6371                     "%s: busy with host reset\n", ioc->name, __func__));
6372                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6373                 return -EBUSY;
6374         }
6375         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6376 
6377         /* don't send if no chance of success */
6378         if (!ioc->active ||
6379             mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6380                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6381                     "%s: ioc not operational, %d, %xh\n",
6382                     ioc->name, __func__, ioc->active,
6383                     mpt_GetIocState(ioc, 0)));
6384                 return -EFAULT;
6385         }
6386 
6387  retry_config:
6388         mutex_lock(&ioc->mptbase_cmds.mutex);
6389         /* init the internal cmd struct */
6390         memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6391         INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6392 
6393         /* Get and Populate a free Frame
6394          */
6395         if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6396                 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6397                 "mpt_config: no msg frames!\n", ioc->name));
6398                 ret = -EAGAIN;
6399                 goto out;
6400         }
6401 
6402         pReq = (Config_t *)mf;
6403         pReq->Action = pCfg->action;
6404         pReq->Reserved = 0;
6405         pReq->ChainOffset = 0;
6406         pReq->Function = MPI_FUNCTION_CONFIG;
6407 
6408         /* Assume page type is not extended and clear "reserved" fields. */
6409         pReq->ExtPageLength = 0;
6410         pReq->ExtPageType = 0;
6411         pReq->MsgFlags = 0;
6412 
6413         for (ii=0; ii < 8; ii++)
6414                 pReq->Reserved2[ii] = 0;
6415 
6416         pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6417         pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6418         pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6419         pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6420 
6421         if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6422                 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6423                 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6424                 pReq->ExtPageType = pExtHdr->ExtPageType;
6425                 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6426 
6427                 /* Page Length must be treated as a reserved field for the
6428                  * extended header.
6429                  */
6430                 pReq->Header.PageLength = 0;
6431         }
6432 
6433         pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6434 
6435         /* Add a SGE to the config request.
6436          */
6437         if (pCfg->dir)
6438                 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6439         else
6440                 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6441 
6442         if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6443             MPI_CONFIG_PAGETYPE_EXTENDED) {
6444                 flagsLength |= pExtHdr->ExtPageLength * 4;
6445                 page_type = pReq->ExtPageType;
6446                 extend_page = 1;
6447         } else {
6448                 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6449                 page_type = pReq->Header.PageType;
6450                 extend_page = 0;
6451         }
6452 
6453         dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6454             "Sending Config request type 0x%x, page 0x%x and action %d\n",
6455             ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6456 
6457         ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6458         timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6459         mpt_put_msg_frame(mpt_base_index, ioc, mf);
6460         timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6461                 timeout);
6462         if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6463                 ret = -ETIME;
6464                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6465                     "Failed Sending Config request type 0x%x, page 0x%x,"
6466                     " action %d, status %xh, time left %ld\n\n",
6467                         ioc->name, page_type, pReq->Header.PageNumber,
6468                         pReq->Action, ioc->mptbase_cmds.status, timeleft));
6469                 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6470                         goto out;
6471                 if (!timeleft) {
6472                         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6473                         if (ioc->ioc_reset_in_progress) {
6474                                 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
6475                                         flags);
6476                                 printk(MYIOC_s_INFO_FMT "%s: host reset in"
6477                                         " progress mpt_config timed out.!!\n",
6478                                         __func__, ioc->name);
6479                                 mutex_unlock(&ioc->mptbase_cmds.mutex);
6480                                 return -EFAULT;
6481                         }
6482                         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6483                         issue_hard_reset = 1;
6484                 }
6485                 goto out;
6486         }
6487 
6488         if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6489                 ret = -1;
6490                 goto out;
6491         }
6492         pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6493         ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6494         if (ret == MPI_IOCSTATUS_SUCCESS) {
6495                 if (extend_page) {
6496                         pCfg->cfghdr.ehdr->ExtPageLength =
6497                             le16_to_cpu(pReply->ExtPageLength);
6498                         pCfg->cfghdr.ehdr->ExtPageType =
6499                             pReply->ExtPageType;
6500                 }
6501                 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6502                 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6503                 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6504                 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6505 
6506         }
6507 
6508         if (retry_count)
6509                 printk(MYIOC_s_INFO_FMT "Retry completed "
6510                     "ret=0x%x timeleft=%ld\n",
6511                     ioc->name, ret, timeleft);
6512 
6513         dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6514              ret, le32_to_cpu(pReply->IOCLogInfo)));
6515 
6516 out:
6517 
6518         CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6519         mutex_unlock(&ioc->mptbase_cmds.mutex);
6520         if (issue_hard_reset) {
6521                 issue_hard_reset = 0;
6522                 printk(MYIOC_s_WARN_FMT
6523                        "Issuing Reset from %s!!, doorbell=0x%08x\n",
6524                        ioc->name, __func__, mpt_GetIocState(ioc, 0));
6525                 if (retry_count == 0) {
6526                         if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6527                                 retry_count++;
6528                 } else
6529                         mpt_HardResetHandler(ioc, CAN_SLEEP);
6530 
6531                 mpt_free_msg_frame(ioc, mf);
6532                 /* attempt one retry for a timed out command */
6533                 if (retry_count < 2) {
6534                         printk(MYIOC_s_INFO_FMT
6535                             "Attempting Retry Config request"
6536                             " type 0x%x, page 0x%x,"
6537                             " action %d\n", ioc->name, page_type,
6538                             pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6539                         retry_count++;
6540                         goto retry_config;
6541                 }
6542         }
6543         return ret;
6544 
6545 }
6546 
6547 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6548 /**
6549  *      mpt_ioc_reset - Base cleanup for hard reset
6550  *      @ioc: Pointer to the adapter structure
6551  *      @reset_phase: Indicates pre- or post-reset functionality
6552  *
6553  *      Remark: Frees resources with internally generated commands.
6554  */
6555 static int
6556 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6557 {
6558         switch (reset_phase) {
6559         case MPT_IOC_SETUP_RESET:
6560                 ioc->taskmgmt_quiesce_io = 1;
6561                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6562                     "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6563                 break;
6564         case MPT_IOC_PRE_RESET:
6565                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6566                     "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6567                 break;
6568         case MPT_IOC_POST_RESET:
6569                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6570                     "%s: MPT_IOC_POST_RESET\n",  ioc->name, __func__));
6571 /* wake up mptbase_cmds */
6572                 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6573                         ioc->mptbase_cmds.status |=
6574                             MPT_MGMT_STATUS_DID_IOCRESET;
6575                         complete(&ioc->mptbase_cmds.done);
6576                 }
6577 /* wake up taskmgmt_cmds */
6578                 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6579                         ioc->taskmgmt_cmds.status |=
6580                                 MPT_MGMT_STATUS_DID_IOCRESET;
6581                         complete(&ioc->taskmgmt_cmds.done);
6582                 }
6583                 break;
6584         default:
6585                 break;
6586         }
6587 
6588         return 1;               /* currently means nothing really */
6589 }
6590 
6591 
6592 #ifdef CONFIG_PROC_FS           /* { */
6593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6594 /*
6595  *      procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6596  */
6597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6598 /**
6599  *      procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6600  *
6601  *      Returns 0 for success, non-zero for failure.
6602  */
6603 static int
6604 procmpt_create(void)
6605 {
6606         mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6607         if (mpt_proc_root_dir == NULL)
6608                 return -ENOTDIR;
6609 
6610         proc_create("summary", S_IRUGO, mpt_proc_root_dir, &mpt_summary_proc_fops);
6611         proc_create("version", S_IRUGO, mpt_proc_root_dir, &mpt_version_proc_fops);
6612         return 0;
6613 }
6614 
6615 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6616 /**
6617  *      procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6618  *
6619  *      Returns 0 for success, non-zero for failure.
6620  */
6621 static void
6622 procmpt_destroy(void)
6623 {
6624         remove_proc_entry("version", mpt_proc_root_dir);
6625         remove_proc_entry("summary", mpt_proc_root_dir);
6626         remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6627 }
6628 
6629 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6630 /*
6631  *      Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6632  */
6633 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6634 
6635 static int mpt_summary_proc_show(struct seq_file *m, void *v)
6636 {
6637         MPT_ADAPTER *ioc = m->private;
6638 
6639         if (ioc) {
6640                 seq_mpt_print_ioc_summary(ioc, m, 1);
6641         } else {
6642                 list_for_each_entry(ioc, &ioc_list, list) {
6643                         seq_mpt_print_ioc_summary(ioc, m, 1);
6644                 }
6645         }
6646 
6647         return 0;
6648 }
6649 
6650 static int mpt_summary_proc_open(struct inode *inode, struct file *file)
6651 {
6652         return single_open(file, mpt_summary_proc_show, PDE_DATA(inode));
6653 }
6654 
6655 static const struct file_operations mpt_summary_proc_fops = {
6656         .owner          = THIS_MODULE,
6657         .open           = mpt_summary_proc_open,
6658         .read           = seq_read,
6659         .llseek         = seq_lseek,
6660         .release        = single_release,
6661 };
6662 
6663 static int mpt_version_proc_show(struct seq_file *m, void *v)
6664 {
6665         u8       cb_idx;
6666         int      scsi, fc, sas, lan, ctl, targ, dmp;
6667         char    *drvname;
6668 
6669         seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6670         seq_printf(m, "  Fusion MPT base driver\n");
6671 
6672         scsi = fc = sas = lan = ctl = targ = dmp = 0;
6673         for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6674                 drvname = NULL;
6675                 if (MptCallbacks[cb_idx]) {
6676                         switch (MptDriverClass[cb_idx]) {
6677                         case MPTSPI_DRIVER:
6678                                 if (!scsi++) drvname = "SPI host";
6679                                 break;
6680                         case MPTFC_DRIVER:
6681                                 if (!fc++) drvname = "FC host";
6682                                 break;
6683                         case MPTSAS_DRIVER:
6684                                 if (!sas++) drvname = "SAS host";
6685                                 break;
6686                         case MPTLAN_DRIVER:
6687                                 if (!lan++) drvname = "LAN";
6688                                 break;
6689                         case MPTSTM_DRIVER:
6690                                 if (!targ++) drvname = "SCSI target";
6691                                 break;
6692                         case MPTCTL_DRIVER:
6693                                 if (!ctl++) drvname = "ioctl";
6694                                 break;
6695                         }
6696 
6697                         if (drvname)
6698                                 seq_printf(m, "  Fusion MPT %s driver\n", drvname);
6699                 }
6700         }
6701 
6702         return 0;
6703 }
6704 
6705 static int mpt_version_proc_open(struct inode *inode, struct file *file)
6706 {
6707         return single_open(file, mpt_version_proc_show, NULL);
6708 }
6709 
6710 static const struct file_operations mpt_version_proc_fops = {
6711         .owner          = THIS_MODULE,
6712         .open           = mpt_version_proc_open,
6713         .read           = seq_read,
6714         .llseek         = seq_lseek,
6715         .release        = single_release,
6716 };
6717 
6718 static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
6719 {
6720         MPT_ADAPTER     *ioc = m->private;
6721         char             expVer[32];
6722         int              sz;
6723         int              p;
6724 
6725         mpt_get_fw_exp_ver(expVer, ioc);
6726 
6727         seq_printf(m, "%s:", ioc->name);
6728         if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6729                 seq_printf(m, "  (f/w download boot flag set)");
6730 //      if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6731 //              seq_printf(m, "  CONFIG_CHECKSUM_FAIL!");
6732 
6733         seq_printf(m, "\n  ProductID = 0x%04x (%s)\n",
6734                         ioc->facts.ProductID,
6735                         ioc->prod_name);
6736         seq_printf(m, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6737         if (ioc->facts.FWImageSize)
6738                 seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
6739         seq_printf(m, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6740         seq_printf(m, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6741         seq_printf(m, "  EventState = 0x%02x\n", ioc->facts.EventState);
6742 
6743         seq_printf(m, "  CurrentHostMfaHighAddr = 0x%08x\n",
6744                         ioc->facts.CurrentHostMfaHighAddr);
6745         seq_printf(m, "  CurrentSenseBufferHighAddr = 0x%08x\n",
6746                         ioc->facts.CurrentSenseBufferHighAddr);
6747 
6748         seq_printf(m, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6749         seq_printf(m, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6750 
6751         seq_printf(m, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6752                                         (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6753         /*
6754          *  Rounding UP to nearest 4-kB boundary here...
6755          */
6756         sz = (ioc->req_sz * ioc->req_depth) + 128;
6757         sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6758         seq_printf(m, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6759                                         ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6760         seq_printf(m, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
6761                                         4*ioc->facts.RequestFrameSize,
6762                                         ioc->facts.GlobalCredits);
6763 
6764         seq_printf(m, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
6765                                         (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6766         sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6767         seq_printf(m, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6768                                         ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6769         seq_printf(m, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
6770                                         ioc->facts.CurReplyFrameSize,
6771                                         ioc->facts.ReplyQueueDepth);
6772 
6773         seq_printf(m, "  MaxDevices = %d\n",
6774                         (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6775         seq_printf(m, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
6776 
6777         /* per-port info */
6778         for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6779                 seq_printf(m, "  PortNumber = %d (of %d)\n",
6780                                 p+1,
6781                                 ioc->facts.NumberOfPorts);
6782                 if (ioc->bus_type == FC) {
6783                         if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6784                                 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6785                                 seq_printf(m, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6786                                                 a[5], a[4], a[3], a[2], a[1], a[0]);
6787                         }
6788                         seq_printf(m, "    WWN = %08X%08X:%08X%08X\n",
6789                                         ioc->fc_port_page0[p].WWNN.High,
6790                                         ioc->fc_port_page0[p].WWNN.Low,
6791                                         ioc->fc_port_page0[p].WWPN.High,
6792                                         ioc->fc_port_page0[p].WWPN.Low);
6793                 }
6794         }
6795 
6796         return 0;
6797 }
6798 
6799 static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file)
6800 {
6801         return single_open(file, mpt_iocinfo_proc_show, PDE_DATA(inode));
6802 }
6803 
6804 static const struct file_operations mpt_iocinfo_proc_fops = {
6805         .owner          = THIS_MODULE,
6806         .open           = mpt_iocinfo_proc_open,
6807         .read           = seq_read,
6808         .llseek         = seq_lseek,
6809         .release        = single_release,
6810 };
6811 #endif          /* CONFIG_PROC_FS } */
6812 
6813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6814 static void
6815 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6816 {
6817         buf[0] ='\0';
6818         if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6819                 sprintf(buf, " (Exp %02d%02d)",
6820                         (ioc->facts.FWVersion.Word >> 16) & 0x00FF,     /* Month */
6821                         (ioc->facts.FWVersion.Word >> 8) & 0x1F);       /* Day */
6822 
6823                 /* insider hack! */
6824                 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6825                         strcat(buf, " [MDBG]");
6826         }
6827 }
6828 
6829 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6830 /**
6831  *      mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6832  *      @ioc: Pointer to MPT_ADAPTER structure
6833  *      @buffer: Pointer to buffer where IOC summary info should be written
6834  *      @size: Pointer to number of bytes we wrote (set by this routine)
6835  *      @len: Offset at which to start writing in buffer
6836  *      @showlan: Display LAN stuff?
6837  *
6838  *      This routine writes (english readable) ASCII text, which represents
6839  *      a summary of IOC information, to a buffer.
6840  */
6841 void
6842 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6843 {
6844         char expVer[32];
6845         int y;
6846 
6847         mpt_get_fw_exp_ver(expVer, ioc);
6848 
6849         /*
6850          *  Shorter summary of attached ioc's...
6851          */
6852         y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6853                         ioc->name,
6854                         ioc->prod_name,
6855                         MPT_FW_REV_MAGIC_ID_STRING,     /* "FwRev=" or somesuch */
6856                         ioc->facts.FWVersion.Word,
6857                         expVer,
6858                         ioc->facts.NumberOfPorts,
6859                         ioc->req_depth);
6860 
6861         if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6862                 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6863                 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6864                         a[5], a[4], a[3], a[2], a[1], a[0]);
6865         }
6866 
6867         y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6868 
6869         if (!ioc->active)
6870                 y += sprintf(buffer+len+y, " (disabled)");
6871 
6872         y += sprintf(buffer+len+y, "\n");
6873 
6874         *size = y;
6875 }
6876 
6877 #ifdef CONFIG_PROC_FS
6878 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
6879 {
6880         char expVer[32];
6881 
6882         mpt_get_fw_exp_ver(expVer, ioc);
6883 
6884         /*
6885          *  Shorter summary of attached ioc's...
6886          */
6887         seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6888                         ioc->name,
6889                         ioc->prod_name,
6890                         MPT_FW_REV_MAGIC_ID_STRING,     /* "FwRev=" or somesuch */
6891                         ioc->facts.FWVersion.Word,
6892                         expVer,
6893                         ioc->facts.NumberOfPorts,
6894                         ioc->req_depth);
6895 
6896         if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6897                 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6898                 seq_printf(m, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6899                         a[5], a[4], a[3], a[2], a[1], a[0]);
6900         }
6901 
6902