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