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