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