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