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