Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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