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