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