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