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