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