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