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