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