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