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