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