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