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