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