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.
8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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.
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.
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.
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
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
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/seq_file.h>
54 #include <linux/slab.h>
55 #include <linux/types.h>
56 #include <linux/pci.h>
57 #include <linux/kdev_t.h>
58 #include <linux/blkdev.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
61 #include <linux/dma-mapping.h>
66 #include <linux/kthread.h>
67 #include <scsi/scsi_host.h>
70 #include "lsi/mpi_log_fc.h"
72 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
73 #define my_NAME "Fusion MPT base driver"
74 #define my_VERSION MPT_LINUX_VERSION_COMMON
75 #define MYNAM "mptbase"
77 MODULE_AUTHOR(MODULEAUTHOR);
78 MODULE_DESCRIPTION(my_NAME);
79 MODULE_LICENSE("GPL");
80 MODULE_VERSION(my_VERSION);
86 static int mpt_msi_enable_spi;
87 module_param(mpt_msi_enable_spi, int, 0);
88 MODULE_PARM_DESC(mpt_msi_enable_spi,
89 " Enable MSI Support for SPI controllers (default=0)");
91 static int mpt_msi_enable_fc;
92 module_param(mpt_msi_enable_fc, int, 0);
93 MODULE_PARM_DESC(mpt_msi_enable_fc,
94 " Enable MSI Support for FC controllers (default=0)");
96 static int mpt_msi_enable_sas;
97 module_param(mpt_msi_enable_sas, int, 0);
98 MODULE_PARM_DESC(mpt_msi_enable_sas,
99 " Enable MSI Support for SAS controllers (default=0)");
101 static int mpt_channel_mapping;
102 module_param(mpt_channel_mapping, int, 0);
103 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
105 static int mpt_debug_level;
106 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
107 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
108 &mpt_debug_level, 0600);
109 MODULE_PARM_DESC(mpt_debug_level,
110 " debug level - refer to mptdebug.h - (default=0)");
112 int mpt_fwfault_debug;
113 EXPORT_SYMBOL(mpt_fwfault_debug);
114 module_param(mpt_fwfault_debug, int, 0600);
115 MODULE_PARM_DESC(mpt_fwfault_debug,
116 "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
118 static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS]
119 [MPT_MAX_CALLBACKNAME_LEN+1];
122 static int mfcounter = 0;
123 #define PRINT_MF_COUNT 20000
126 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
131 #define WHOINIT_UNKNOWN 0xAA
133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
137 /* Adapter link 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];
149 #ifdef CONFIG_PROC_FS
150 static struct proc_dir_entry *mpt_proc_root_dir;
154 * Driver Callback Index's
156 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
157 static u8 last_drv_idx;
159 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
163 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
164 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
165 MPT_FRAME_HDR *reply);
166 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
167 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
169 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
170 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
171 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
172 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
174 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
175 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
176 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
177 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
178 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
179 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
180 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
181 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
182 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
183 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
184 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
185 static int PrimeIocFifos(MPT_ADAPTER *ioc);
186 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
187 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
188 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
189 static int GetLanConfigPages(MPT_ADAPTER *ioc);
190 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
191 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
192 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
193 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
194 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
195 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
196 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
197 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
199 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
200 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
201 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
203 #ifdef CONFIG_PROC_FS
204 static const struct file_operations mpt_summary_proc_fops;
205 static const struct file_operations mpt_version_proc_fops;
206 static const struct file_operations mpt_iocinfo_proc_fops;
208 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
210 static int ProcessEventNotification(MPT_ADAPTER *ioc,
211 EventNotificationReply_t *evReply, int *evHandlers);
212 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
213 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
214 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
215 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
216 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
217 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
219 /* module entry point */
220 static int __init fusion_init (void);
221 static void __exit fusion_exit (void);
223 #define CHIPREG_READ32(addr) readl_relaxed(addr)
224 #define CHIPREG_READ32_dmasync(addr) readl(addr)
225 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
226 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
227 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
230 pci_disable_io_access(struct pci_dev *pdev)
234 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
236 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
240 pci_enable_io_access(struct pci_dev *pdev)
244 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
246 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
249 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
251 int ret = param_set_int(val, kp);
257 list_for_each_entry(ioc, &ioc_list, list)
258 ioc->debug_level = mpt_debug_level;
263 * mpt_get_cb_idx - obtain cb_idx for registered driver
264 * @dclass: class driver enum
266 * Returns cb_idx, or zero means it wasn't found
269 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
273 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
274 if (MptDriverClass[cb_idx] == dclass)
280 * mpt_is_discovery_complete - determine if discovery has completed
281 * @ioc: per adatper instance
283 * Returns 1 when discovery completed, else zero.
286 mpt_is_discovery_complete(MPT_ADAPTER *ioc)
288 ConfigExtendedPageHeader_t hdr;
290 SasIOUnitPage0_t *buffer;
291 dma_addr_t dma_handle;
294 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
295 memset(&cfg, 0, sizeof(CONFIGPARMS));
296 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
297 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
298 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
299 cfg.cfghdr.ehdr = &hdr;
300 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
302 if ((mpt_config(ioc, &cfg)))
304 if (!hdr.ExtPageLength)
307 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
312 cfg.physAddr = dma_handle;
313 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
315 if ((mpt_config(ioc, &cfg)))
316 goto out_free_consistent;
318 if (!(buffer->PhyData[0].PortFlags &
319 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
323 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
331 * mpt_remove_dead_ioc_func - kthread context to remove dead ioc
332 * @arg: input argument, used to derive ioc
334 * Return 0 if controller is removed from pci subsystem.
335 * Return -1 for other case.
337 static int mpt_remove_dead_ioc_func(void *arg)
339 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
340 struct pci_dev *pdev;
349 pci_stop_and_remove_bus_device_locked(pdev);
356 * mpt_fault_reset_work - work performed on workq after ioc fault
357 * @work: input argument, used to derive ioc
361 mpt_fault_reset_work(struct work_struct *work)
364 container_of(work, MPT_ADAPTER, fault_reset_work.work);
369 struct task_struct *p;
371 if (ioc->ioc_reset_in_progress || !ioc->active)
375 ioc_raw_state = mpt_GetIocState(ioc, 0);
376 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_MASK) {
377 printk(MYIOC_s_INFO_FMT "%s: IOC is non-operational !!!!\n",
378 ioc->name, __func__);
381 * Call mptscsih_flush_pending_cmds callback so that we
382 * flush all pending commands back to OS.
383 * This call is required to aovid deadlock at block layer.
384 * Dead IOC will fail to do diag reset,and this call is safe
385 * since dead ioc will never return any command back from HW.
387 hd = shost_priv(ioc->sh);
388 ioc->schedule_dead_ioc_flush_running_cmds(hd);
390 /*Remove the Dead Host */
391 p = kthread_run(mpt_remove_dead_ioc_func, ioc,
392 "mpt_dead_ioc_%d", ioc->id);
394 printk(MYIOC_s_ERR_FMT
395 "%s: Running mpt_dead_ioc thread failed !\n",
396 ioc->name, __func__);
398 printk(MYIOC_s_WARN_FMT
399 "%s: Running mpt_dead_ioc thread success !\n",
400 ioc->name, __func__);
402 return; /* don't rearm timer */
405 if ((ioc_raw_state & MPI_IOC_STATE_MASK)
406 == MPI_IOC_STATE_FAULT) {
407 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
408 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
409 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
410 ioc->name, __func__);
411 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
412 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
413 __func__, (rc == 0) ? "success" : "failed");
414 ioc_raw_state = mpt_GetIocState(ioc, 0);
415 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
416 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
417 "reset (%04xh)\n", ioc->name, ioc_raw_state &
418 MPI_DOORBELL_DATA_MASK);
419 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
420 if ((mpt_is_discovery_complete(ioc))) {
421 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
422 "discovery_quiesce_io flag\n", ioc->name));
423 ioc->sas_discovery_quiesce_io = 0;
429 * Take turns polling alternate controller
434 /* rearm the timer */
435 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
436 if (ioc->reset_work_q)
437 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
438 msecs_to_jiffies(MPT_POLLING_INTERVAL));
439 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
444 * Process turbo (context) reply...
447 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
449 MPT_FRAME_HDR *mf = NULL;
450 MPT_FRAME_HDR *mr = NULL;
454 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
457 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
458 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
459 req_idx = pa & 0x0000FFFF;
460 cb_idx = (pa & 0x00FF0000) >> 16;
461 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
463 case MPI_CONTEXT_REPLY_TYPE_LAN:
464 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
466 * Blind set of mf to NULL here was fatal
467 * after lan_reply says "freeme"
468 * Fix sort of combined with an optimization here;
469 * added explicit check for case where lan_reply
470 * was just returning 1 and doing nothing else.
471 * For this case skip the callback, but set up
472 * proper mf value first here:-)
474 if ((pa & 0x58000000) == 0x58000000) {
475 req_idx = pa & 0x0000FFFF;
476 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
477 mpt_free_msg_frame(ioc, mf);
482 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
484 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
485 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
486 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
493 /* Check for (valid) IO callback! */
494 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
495 MptCallbacks[cb_idx] == NULL) {
496 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
497 __func__, ioc->name, cb_idx);
501 if (MptCallbacks[cb_idx](ioc, mf, mr))
502 mpt_free_msg_frame(ioc, mf);
508 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
519 /* non-TURBO reply! Hmmm, something may be up...
520 * Newest turbo reply mechanism; get address
521 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
524 /* Map DMA address of reply header to cpu address.
525 * pa is 32 bits - but the dma address may be 32 or 64 bits
526 * get offset based only only the low addresses
529 reply_dma_low = (pa <<= 1);
530 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
531 (reply_dma_low - ioc->reply_frames_low_dma));
533 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
534 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
535 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
537 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
538 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
539 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
541 /* Check/log IOC log info
543 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
544 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
545 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
546 if (ioc->bus_type == FC)
547 mpt_fc_log_info(ioc, log_info);
548 else if (ioc->bus_type == SPI)
549 mpt_spi_log_info(ioc, log_info);
550 else if (ioc->bus_type == SAS)
551 mpt_sas_log_info(ioc, log_info, cb_idx);
554 if (ioc_stat & MPI_IOCSTATUS_MASK)
555 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
557 /* Check for (valid) IO callback! */
558 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
559 MptCallbacks[cb_idx] == NULL) {
560 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
561 __func__, ioc->name, cb_idx);
566 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
569 /* Flush (non-TURBO) reply with a WRITE! */
570 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
573 mpt_free_msg_frame(ioc, mf);
577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
579 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
580 * @irq: irq number (not used)
581 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
583 * This routine is registered via the request_irq() kernel API call,
584 * and handles all interrupts generated from a specific MPT adapter
585 * (also referred to as a IO Controller or IOC).
586 * This routine must clear the interrupt from the adapter and does
587 * so by reading the reply FIFO. Multiple replies may be processed
588 * per single call to this routine.
590 * This routine handles register-level access of the adapter but
591 * dispatches (calls) a protocol-specific callback routine to handle
592 * the protocol-specific details of the MPT request completion.
595 mpt_interrupt(int irq, void *bus_id)
597 MPT_ADAPTER *ioc = bus_id;
598 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
600 if (pa == 0xFFFFFFFF)
604 * Drain the reply FIFO!
607 if (pa & MPI_ADDRESS_REPLY_A_BIT)
610 mpt_turbo_reply(ioc, pa);
611 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
612 } while (pa != 0xFFFFFFFF);
617 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
619 * mptbase_reply - MPT base driver's callback routine
620 * @ioc: Pointer to MPT_ADAPTER structure
621 * @req: Pointer to original MPT request frame
622 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
624 * MPT base driver's callback routine; all base driver
625 * "internal" request/reply processing is routed here.
626 * Currently used for EventNotification and EventAck handling.
628 * Returns 1 indicating original alloc'd request frame ptr
629 * should be freed, or 0 if it shouldn't.
632 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
634 EventNotificationReply_t *pEventReply;
639 switch (reply->u.hdr.Function) {
640 case MPI_FUNCTION_EVENT_NOTIFICATION:
641 pEventReply = (EventNotificationReply_t *)reply;
643 ProcessEventNotification(ioc, pEventReply, &evHandlers);
644 event = le32_to_cpu(pEventReply->Event) & 0xFF;
645 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
647 if (event != MPI_EVENT_EVENT_CHANGE)
649 case MPI_FUNCTION_CONFIG:
650 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
651 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
652 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
653 memcpy(ioc->mptbase_cmds.reply, reply,
654 min(MPT_DEFAULT_FRAME_SIZE,
655 4 * reply->u.reply.MsgLength));
656 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
657 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
658 complete(&ioc->mptbase_cmds.done);
661 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
664 case MPI_FUNCTION_EVENT_ACK:
665 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
666 "EventAck reply received\n", ioc->name));
669 printk(MYIOC_s_ERR_FMT
670 "Unexpected msg function (=%02Xh) reply received!\n",
671 ioc->name, reply->u.hdr.Function);
676 * Conditionally tell caller to free the original
677 * EventNotification/EventAck/unexpected request frame!
682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
684 * mpt_register - Register protocol-specific main callback handler.
685 * @cbfunc: callback function pointer
686 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
687 * @func_name: call function's name
689 * This routine is called by a protocol-specific driver (SCSI host,
690 * LAN, SCSI target) to register its reply callback routine. Each
691 * protocol-specific driver must do this before it will be able to
692 * use any IOC resources, such as obtaining request frames.
694 * NOTES: The SCSI protocol driver currently calls this routine thrice
695 * in order to register separate callbacks; one for "normal" SCSI IO;
696 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
698 * Returns u8 valued "handle" in the range (and S.O.D. order)
699 * {N,...,7,6,5,...,1} if successful.
700 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
701 * considered an error by the caller.
704 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
707 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
710 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
711 * (slot/handle 0 is reserved!)
713 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
714 if (MptCallbacks[cb_idx] == NULL) {
715 MptCallbacks[cb_idx] = cbfunc;
716 MptDriverClass[cb_idx] = dclass;
717 MptEvHandlers[cb_idx] = NULL;
718 last_drv_idx = cb_idx;
719 strlcpy(MptCallbacksName[cb_idx], func_name,
720 MPT_MAX_CALLBACKNAME_LEN+1);
728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
730 * mpt_deregister - Deregister a protocol drivers resources.
731 * @cb_idx: previously registered callback handle
733 * Each protocol-specific driver should call this routine when its
734 * module is unloaded.
737 mpt_deregister(u8 cb_idx)
739 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
740 MptCallbacks[cb_idx] = NULL;
741 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
742 MptEvHandlers[cb_idx] = NULL;
748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
750 * mpt_event_register - Register protocol-specific event callback handler.
751 * @cb_idx: previously registered (via mpt_register) callback handle
752 * @ev_cbfunc: callback function
754 * This routine can be called by one or more protocol-specific drivers
755 * if/when they choose to be notified of MPT events.
757 * Returns 0 for success.
760 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
762 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
765 MptEvHandlers[cb_idx] = ev_cbfunc;
769 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
771 * mpt_event_deregister - Deregister protocol-specific event callback handler
772 * @cb_idx: previously registered callback handle
774 * Each protocol-specific driver should call this routine
775 * when it does not (or can no longer) handle events,
776 * or when its module is unloaded.
779 mpt_event_deregister(u8 cb_idx)
781 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
784 MptEvHandlers[cb_idx] = NULL;
787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
789 * mpt_reset_register - Register protocol-specific IOC reset handler.
790 * @cb_idx: previously registered (via mpt_register) callback handle
791 * @reset_func: reset function
793 * This routine can be called by one or more protocol-specific drivers
794 * if/when they choose to be notified of IOC resets.
796 * Returns 0 for success.
799 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
801 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
804 MptResetHandlers[cb_idx] = reset_func;
808 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
810 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
811 * @cb_idx: previously registered callback handle
813 * Each protocol-specific driver should call this routine
814 * when it does not (or can no longer) handle IOC reset handling,
815 * or when its module is unloaded.
818 mpt_reset_deregister(u8 cb_idx)
820 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
823 MptResetHandlers[cb_idx] = NULL;
826 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
828 * mpt_device_driver_register - Register device driver hooks
829 * @dd_cbfunc: driver callbacks struct
830 * @cb_idx: MPT protocol driver index
833 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
836 const struct pci_device_id *id;
838 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
841 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
843 /* call per pci device probe entry point */
844 list_for_each_entry(ioc, &ioc_list, list) {
845 id = ioc->pcidev->driver ?
846 ioc->pcidev->driver->id_table : NULL;
847 if (dd_cbfunc->probe)
848 dd_cbfunc->probe(ioc->pcidev, id);
854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
856 * mpt_device_driver_deregister - DeRegister device driver hooks
857 * @cb_idx: MPT protocol driver index
860 mpt_device_driver_deregister(u8 cb_idx)
862 struct mpt_pci_driver *dd_cbfunc;
865 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
868 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
870 list_for_each_entry(ioc, &ioc_list, list) {
871 if (dd_cbfunc->remove)
872 dd_cbfunc->remove(ioc->pcidev);
875 MptDeviceDriverHandlers[cb_idx] = NULL;
879 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
881 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
882 * @cb_idx: Handle of registered MPT protocol driver
883 * @ioc: Pointer to MPT adapter structure
885 * Obtain an MPT request frame from the pool (of 1024) that are
886 * allocated per MPT adapter.
888 * Returns pointer to a MPT request frame or %NULL if none are available
889 * or IOC is not active.
892 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
896 u16 req_idx; /* Request index */
898 /* validate handle and ioc identifier */
902 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
903 "returning NULL!\n", ioc->name);
906 /* If interrupts are not attached, do not return a request frame */
910 spin_lock_irqsave(&ioc->FreeQlock, flags);
911 if (!list_empty(&ioc->FreeQ)) {
914 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
915 u.frame.linkage.list);
916 list_del(&mf->u.frame.linkage.list);
917 mf->u.frame.linkage.arg1 = 0;
918 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
919 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
921 req_idx = req_offset / ioc->req_sz;
922 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
923 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
924 /* Default, will be changed if necessary in SG generation */
925 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
932 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
936 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
937 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
940 if (mfcounter == PRINT_MF_COUNT)
941 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
942 ioc->mfcnt, ioc->req_depth);
945 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
946 ioc->name, cb_idx, ioc->id, mf));
950 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
952 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
953 * @cb_idx: Handle of registered MPT protocol driver
954 * @ioc: Pointer to MPT adapter structure
955 * @mf: Pointer to MPT request frame
957 * This routine posts an MPT request frame to the request post FIFO of a
958 * specific MPT adapter.
961 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
965 u16 req_idx; /* Request index */
967 /* ensure values are reset properly! */
968 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
969 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
971 req_idx = req_offset / ioc->req_sz;
972 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
973 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
975 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
977 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
978 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
979 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
980 ioc->RequestNB[req_idx]));
981 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
985 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
986 * @cb_idx: Handle of registered MPT protocol driver
987 * @ioc: Pointer to MPT adapter structure
988 * @mf: Pointer to MPT request frame
990 * Send a protocol-specific MPT request frame to an IOC using
991 * hi-priority request queue.
993 * This routine posts an MPT request frame to the request post FIFO of a
994 * specific MPT adapter.
997 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1001 u16 req_idx; /* Request index */
1003 /* ensure values are reset properly! */
1004 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1005 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
1006 req_idx = req_offset / ioc->req_sz;
1007 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
1008 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
1010 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
1012 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
1013 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
1014 ioc->name, mf_dma_addr, req_idx));
1015 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
1018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1020 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
1021 * @ioc: Pointer to MPT adapter structure
1022 * @mf: Pointer to MPT request frame
1024 * This routine places a MPT request frame back on the MPT adapter's
1028 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1030 unsigned long flags;
1032 /* Put Request back on FreeQ! */
1033 spin_lock_irqsave(&ioc->FreeQlock, flags);
1034 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
1036 /* signature to know if this mf is freed */
1037 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
1038 list_add(&mf->u.frame.linkage.list, &ioc->FreeQ);
1043 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1046 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1048 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1049 * @pAddr: virtual address for SGE
1050 * @flagslength: SGE flags and data transfer length
1051 * @dma_addr: Physical address
1053 * This routine places a MPT request frame back on the MPT adapter's
1057 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1059 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1060 pSge->FlagsLength = cpu_to_le32(flagslength);
1061 pSge->Address = cpu_to_le32(dma_addr);
1065 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1066 * @pAddr: virtual address for SGE
1067 * @flagslength: SGE flags and data transfer length
1068 * @dma_addr: Physical address
1070 * This routine places a MPT request frame back on the MPT adapter's
1074 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1076 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1077 pSge->Address.Low = cpu_to_le32
1078 (lower_32_bits(dma_addr));
1079 pSge->Address.High = cpu_to_le32
1080 (upper_32_bits(dma_addr));
1081 pSge->FlagsLength = cpu_to_le32
1082 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1086 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1087 * @pAddr: virtual address for SGE
1088 * @flagslength: SGE flags and data transfer length
1089 * @dma_addr: Physical address
1091 * This routine places a MPT request frame back on the MPT adapter's
1095 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1097 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1100 pSge->Address.Low = cpu_to_le32
1101 (lower_32_bits(dma_addr));
1102 tmp = (u32)(upper_32_bits(dma_addr));
1105 * 1078 errata workaround for the 36GB limitation
1107 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1109 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1111 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1112 printk(KERN_DEBUG "1078 P0M2 addressing for "
1113 "addr = 0x%llx len = %d\n",
1114 (unsigned long long)dma_addr,
1115 MPI_SGE_LENGTH(flagslength));
1118 pSge->Address.High = cpu_to_le32(tmp);
1119 pSge->FlagsLength = cpu_to_le32(
1120 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1123 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1125 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1126 * @pAddr: virtual address for SGE
1127 * @next: nextChainOffset value (u32's)
1128 * @length: length of next SGL segment
1129 * @dma_addr: Physical address
1133 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1135 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1136 pChain->Length = cpu_to_le16(length);
1137 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1138 pChain->NextChainOffset = next;
1139 pChain->Address = cpu_to_le32(dma_addr);
1142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1144 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1145 * @pAddr: virtual address for SGE
1146 * @next: nextChainOffset value (u32's)
1147 * @length: length of next SGL segment
1148 * @dma_addr: Physical address
1152 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1154 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1155 u32 tmp = dma_addr & 0xFFFFFFFF;
1157 pChain->Length = cpu_to_le16(length);
1158 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1159 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1161 pChain->NextChainOffset = next;
1163 pChain->Address.Low = cpu_to_le32(tmp);
1164 tmp = (u32)(upper_32_bits(dma_addr));
1165 pChain->Address.High = cpu_to_le32(tmp);
1168 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1170 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1171 * @cb_idx: Handle of registered MPT protocol driver
1172 * @ioc: Pointer to MPT adapter structure
1173 * @reqBytes: Size of the request in bytes
1174 * @req: Pointer to MPT request frame
1175 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1177 * This routine is used exclusively to send MptScsiTaskMgmt
1178 * requests since they are required to be sent via doorbell handshake.
1180 * NOTE: It is the callers responsibility to byte-swap fields in the
1181 * request which are greater than 1 byte in size.
1183 * Returns 0 for success, non-zero for failure.
1186 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1192 /* State is known to be good upon entering
1193 * this function so issue the bus reset
1198 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1199 * setting cb_idx/req_idx. But ONLY if this request
1200 * is in proper (pre-alloc'd) request buffer range...
1202 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1203 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1204 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1205 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1206 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1209 /* Make sure there are no doorbells */
1210 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1212 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1213 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1214 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1216 /* Wait for IOC doorbell int */
1217 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1221 /* Read doorbell and check for active bit */
1222 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1225 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1228 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1230 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1234 /* Send request via doorbell handshake */
1235 req_as_bytes = (u8 *) req;
1236 for (ii = 0; ii < reqBytes/4; ii++) {
1239 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1240 (req_as_bytes[(ii*4) + 1] << 8) |
1241 (req_as_bytes[(ii*4) + 2] << 16) |
1242 (req_as_bytes[(ii*4) + 3] << 24));
1243 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1244 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1250 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1255 /* Make sure there are no doorbells */
1256 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1263 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1264 * @ioc: Pointer to MPT adapter structure
1265 * @access_control_value: define bits below
1266 * @sleepFlag: Specifies whether the process can sleep
1268 * Provides mechanism for the host driver to control the IOC's
1269 * Host Page Buffer access.
1271 * Access Control Value - bits[15:12]
1273 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1274 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1275 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1277 * Returns 0 for success, non-zero for failure.
1281 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1285 /* return if in use */
1286 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1287 & MPI_DOORBELL_ACTIVE)
1290 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1292 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1293 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1294 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1295 (access_control_value<<12)));
1297 /* Wait for IOC to clear Doorbell Status bit */
1298 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1304 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1306 * mpt_host_page_alloc - allocate system memory for the fw
1307 * @ioc: Pointer to pointer to IOC adapter
1308 * @ioc_init: Pointer to ioc init config page
1310 * If we already allocated memory in past, then resend the same pointer.
1311 * Returns 0 for success, non-zero for failure.
1314 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1318 u32 host_page_buffer_sz=0;
1320 if(!ioc->HostPageBuffer) {
1322 host_page_buffer_sz =
1323 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1325 if(!host_page_buffer_sz)
1326 return 0; /* fw doesn't need any host buffers */
1328 /* spin till we get enough memory */
1329 while(host_page_buffer_sz > 0) {
1331 if((ioc->HostPageBuffer = pci_alloc_consistent(
1333 host_page_buffer_sz,
1334 &ioc->HostPageBuffer_dma)) != NULL) {
1336 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1337 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1338 ioc->name, ioc->HostPageBuffer,
1339 (u32)ioc->HostPageBuffer_dma,
1340 host_page_buffer_sz));
1341 ioc->alloc_total += host_page_buffer_sz;
1342 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1346 host_page_buffer_sz -= (4*1024);
1350 if(!ioc->HostPageBuffer) {
1351 printk(MYIOC_s_ERR_FMT
1352 "Failed to alloc memory for host_page_buffer!\n",
1357 psge = (char *)&ioc_init->HostPageBufferSGE;
1358 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1359 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1360 MPI_SGE_FLAGS_HOST_TO_IOC |
1361 MPI_SGE_FLAGS_END_OF_BUFFER;
1362 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1363 flags_length |= ioc->HostPageBuffer_sz;
1364 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1365 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1370 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1372 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1373 * @iocid: IOC unique identifier (integer)
1374 * @iocpp: Pointer to pointer to IOC adapter
1376 * Given a unique IOC identifier, set pointer to the associated MPT
1377 * adapter structure.
1379 * Returns iocid and sets iocpp if iocid is found.
1380 * Returns -1 if iocid is not found.
1383 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1387 list_for_each_entry(ioc,&ioc_list,list) {
1388 if (ioc->id == iocid) {
1399 * mpt_get_product_name - returns product string
1400 * @vendor: pci vendor id
1401 * @device: pci device id
1402 * @revision: pci revision id
1403 * @prod_name: string returned
1405 * Returns product string displayed when driver loads,
1406 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1410 mpt_get_product_name(u16 vendor, u16 device, u8 revision)
1412 char *product_str = NULL;
1414 if (vendor == PCI_VENDOR_ID_BROCADE) {
1417 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1421 product_str = "BRE040 A0";
1424 product_str = "BRE040 A1";
1427 product_str = "BRE040";
1437 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1438 product_str = "LSIFC909 B1";
1440 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1441 product_str = "LSIFC919 B0";
1443 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1444 product_str = "LSIFC929 B0";
1446 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1447 if (revision < 0x80)
1448 product_str = "LSIFC919X A0";
1450 product_str = "LSIFC919XL A1";
1452 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1453 if (revision < 0x80)
1454 product_str = "LSIFC929X A0";
1456 product_str = "LSIFC929XL A1";
1458 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1459 product_str = "LSIFC939X A1";
1461 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1462 product_str = "LSIFC949X A1";
1464 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1468 product_str = "LSIFC949E A0";
1471 product_str = "LSIFC949E A1";
1474 product_str = "LSIFC949E";
1478 case MPI_MANUFACTPAGE_DEVID_53C1030:
1482 product_str = "LSI53C1030 A0";
1485 product_str = "LSI53C1030 B0";
1488 product_str = "LSI53C1030 B1";
1491 product_str = "LSI53C1030 B2";
1494 product_str = "LSI53C1030 C0";
1497 product_str = "LSI53C1030T A0";
1500 product_str = "LSI53C1030T A2";
1503 product_str = "LSI53C1030T A3";
1506 product_str = "LSI53C1020A A1";
1509 product_str = "LSI53C1030";
1513 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1517 product_str = "LSI53C1035 A2";
1520 product_str = "LSI53C1035 B0";
1523 product_str = "LSI53C1035";
1527 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1531 product_str = "LSISAS1064 A1";
1534 product_str = "LSISAS1064 A2";
1537 product_str = "LSISAS1064 A3";
1540 product_str = "LSISAS1064 A4";
1543 product_str = "LSISAS1064";
1547 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1551 product_str = "LSISAS1064E A0";
1554 product_str = "LSISAS1064E B0";
1557 product_str = "LSISAS1064E B1";
1560 product_str = "LSISAS1064E B2";
1563 product_str = "LSISAS1064E B3";
1566 product_str = "LSISAS1064E";
1570 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1574 product_str = "LSISAS1068 A0";
1577 product_str = "LSISAS1068 B0";
1580 product_str = "LSISAS1068 B1";
1583 product_str = "LSISAS1068";
1587 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1591 product_str = "LSISAS1068E A0";
1594 product_str = "LSISAS1068E B0";
1597 product_str = "LSISAS1068E B1";
1600 product_str = "LSISAS1068E B2";
1603 product_str = "LSISAS1068E B3";
1606 product_str = "LSISAS1068E";
1610 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1614 product_str = "LSISAS1078 A0";
1617 product_str = "LSISAS1078 B0";
1620 product_str = "LSISAS1078 C0";
1623 product_str = "LSISAS1078 C1";
1626 product_str = "LSISAS1078 C2";
1629 product_str = "LSISAS1078";
1640 * mpt_mapresources - map in memory mapped io
1641 * @ioc: Pointer to pointer to IOC adapter
1645 mpt_mapresources(MPT_ADAPTER *ioc)
1649 resource_size_t mem_phys;
1654 struct pci_dev *pdev;
1657 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1658 if (pci_enable_device_mem(pdev)) {
1659 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1660 "failed\n", ioc->name);
1663 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1664 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1665 "MEM failed\n", ioc->name);
1666 goto out_pci_disable_device;
1669 if (sizeof(dma_addr_t) > 4) {
1670 const uint64_t required_mask = dma_get_required_mask
1672 if (required_mask > DMA_BIT_MASK(32)
1673 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1674 && !pci_set_consistent_dma_mask(pdev,
1675 DMA_BIT_MASK(64))) {
1676 ioc->dma_mask = DMA_BIT_MASK(64);
1677 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1678 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1680 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1681 && !pci_set_consistent_dma_mask(pdev,
1682 DMA_BIT_MASK(32))) {
1683 ioc->dma_mask = DMA_BIT_MASK(32);
1684 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1685 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1688 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1689 ioc->name, pci_name(pdev));
1690 goto out_pci_release_region;
1693 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1694 && !pci_set_consistent_dma_mask(pdev,
1695 DMA_BIT_MASK(32))) {
1696 ioc->dma_mask = DMA_BIT_MASK(32);
1697 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1698 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1701 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1702 ioc->name, pci_name(pdev));
1703 goto out_pci_release_region;
1707 mem_phys = msize = 0;
1709 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1710 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1713 /* Get I/O space! */
1714 port = pci_resource_start(pdev, ii);
1715 psize = pci_resource_len(pdev, ii);
1720 mem_phys = pci_resource_start(pdev, ii);
1721 msize = pci_resource_len(pdev, ii);
1724 ioc->mem_size = msize;
1727 /* Get logical ptr for PciMem0 space */
1728 /*mem = ioremap(mem_phys, msize);*/
1729 mem = ioremap(mem_phys, msize);
1731 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1732 " memory!\n", ioc->name);
1734 goto out_pci_release_region;
1737 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1738 ioc->name, mem, (unsigned long long)mem_phys));
1740 ioc->mem_phys = mem_phys;
1741 ioc->chip = (SYSIF_REGS __iomem *)mem;
1743 /* Save Port IO values in case we need to do downloadboot */
1744 ioc->pio_mem_phys = port;
1745 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1749 out_pci_release_region:
1750 pci_release_selected_regions(pdev, ioc->bars);
1751 out_pci_disable_device:
1752 pci_disable_device(pdev);
1756 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1758 * mpt_attach - Install a PCI intelligent MPT adapter.
1759 * @pdev: Pointer to pci_dev structure
1760 * @id: PCI device ID information
1762 * This routine performs all the steps necessary to bring the IOC of
1763 * a MPT adapter to a OPERATIONAL state. This includes registering
1764 * memory regions, registering the interrupt, and allocating request
1765 * and reply memory pools.
1767 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1770 * Returns 0 for success, non-zero for failure.
1772 * TODO: Add support for polled controllers
1775 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1781 static int mpt_ids = 0;
1782 #ifdef CONFIG_PROC_FS
1783 struct proc_dir_entry *dent;
1786 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1788 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1792 ioc->id = mpt_ids++;
1793 sprintf(ioc->name, "ioc%d", ioc->id);
1794 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1797 * set initial debug level
1798 * (refer to mptdebug.h)
1801 ioc->debug_level = mpt_debug_level;
1802 if (mpt_debug_level)
1803 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1805 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1808 if (mpt_mapresources(ioc)) {
1814 * Setting up proper handlers for scatter gather handling
1816 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1817 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1818 ioc->add_sge = &mpt_add_sge_64bit_1078;
1820 ioc->add_sge = &mpt_add_sge_64bit;
1821 ioc->add_chain = &mpt_add_chain_64bit;
1822 ioc->sg_addr_size = 8;
1824 ioc->add_sge = &mpt_add_sge;
1825 ioc->add_chain = &mpt_add_chain;
1826 ioc->sg_addr_size = 4;
1828 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1830 ioc->alloc_total = sizeof(MPT_ADAPTER);
1831 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1832 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1835 spin_lock_init(&ioc->taskmgmt_lock);
1836 mutex_init(&ioc->internal_cmds.mutex);
1837 init_completion(&ioc->internal_cmds.done);
1838 mutex_init(&ioc->mptbase_cmds.mutex);
1839 init_completion(&ioc->mptbase_cmds.done);
1840 mutex_init(&ioc->taskmgmt_cmds.mutex);
1841 init_completion(&ioc->taskmgmt_cmds.done);
1843 /* Initialize the event logging.
1845 ioc->eventTypes = 0; /* None */
1846 ioc->eventContext = 0;
1847 ioc->eventLogSize = 0;
1855 ioc->cached_fw = NULL;
1857 /* Initialize SCSI Config Data structure
1859 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1861 /* Initialize the fc rport list head.
1863 INIT_LIST_HEAD(&ioc->fc_rports);
1865 /* Find lookup slot. */
1866 INIT_LIST_HEAD(&ioc->list);
1869 /* Initialize workqueue */
1870 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1872 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1873 "mpt_poll_%d", ioc->id);
1875 create_singlethread_workqueue(ioc->reset_work_q_name);
1876 if (!ioc->reset_work_q) {
1877 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1879 pci_release_selected_regions(pdev, ioc->bars);
1884 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1885 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1887 ioc->prod_name = mpt_get_product_name(pdev->vendor, pdev->device,
1890 switch (pdev->device)
1892 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1893 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1894 ioc->errata_flag_1064 = 1;
1895 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1896 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1897 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1898 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1902 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1903 if (pdev->revision < XL_929) {
1904 /* 929X Chip Fix. Set Split transactions level
1905 * for PCIX. Set MOST bits to zero.
1907 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1909 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1911 /* 929XL Chip Fix. Set MMRBC to 0x08.
1913 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1915 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1920 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1921 /* 919X Chip Fix. Set Split transactions level
1922 * for PCIX. Set MOST bits to zero.
1924 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1926 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1930 case MPI_MANUFACTPAGE_DEVID_53C1030:
1931 /* 1030 Chip Fix. Disable Split transactions
1932 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1934 if (pdev->revision < C0_1030) {
1935 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1937 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1940 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1941 ioc->bus_type = SPI;
1944 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1945 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1946 ioc->errata_flag_1064 = 1;
1947 ioc->bus_type = SAS;
1950 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1951 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1952 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1953 ioc->bus_type = SAS;
1958 switch (ioc->bus_type) {
1961 ioc->msi_enable = mpt_msi_enable_sas;
1965 ioc->msi_enable = mpt_msi_enable_spi;
1969 ioc->msi_enable = mpt_msi_enable_fc;
1973 ioc->msi_enable = 0;
1977 ioc->fw_events_off = 1;
1979 if (ioc->errata_flag_1064)
1980 pci_disable_io_access(pdev);
1982 spin_lock_init(&ioc->FreeQlock);
1985 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1987 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1989 /* Set IOC ptr in the pcidev's driver data. */
1990 pci_set_drvdata(ioc->pcidev, ioc);
1992 /* Set lookup ptr. */
1993 list_add_tail(&ioc->list, &ioc_list);
1995 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1997 mpt_detect_bound_ports(ioc, pdev);
1999 INIT_LIST_HEAD(&ioc->fw_event_list);
2000 spin_lock_init(&ioc->fw_event_lock);
2001 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
2002 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
2004 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2006 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
2009 list_del(&ioc->list);
2011 ioc->alt_ioc->alt_ioc = NULL;
2012 iounmap(ioc->memmap);
2014 pci_release_selected_regions(pdev, ioc->bars);
2016 destroy_workqueue(ioc->reset_work_q);
2017 ioc->reset_work_q = NULL;
2020 pci_set_drvdata(pdev, NULL);
2024 /* call per device driver probe entry point */
2025 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2026 if(MptDeviceDriverHandlers[cb_idx] &&
2027 MptDeviceDriverHandlers[cb_idx]->probe) {
2028 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
2032 #ifdef CONFIG_PROC_FS
2034 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
2036 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
2038 proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc);
2039 proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc);
2044 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2045 msecs_to_jiffies(MPT_POLLING_INTERVAL));
2050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2052 * mpt_detach - Remove a PCI intelligent MPT adapter.
2053 * @pdev: Pointer to pci_dev structure
2057 mpt_detach(struct pci_dev *pdev)
2059 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2062 unsigned long flags;
2063 struct workqueue_struct *wq;
2066 * Stop polling ioc for fault condition
2068 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2069 wq = ioc->reset_work_q;
2070 ioc->reset_work_q = NULL;
2071 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2072 cancel_delayed_work(&ioc->fault_reset_work);
2073 destroy_workqueue(wq);
2075 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2076 wq = ioc->fw_event_q;
2077 ioc->fw_event_q = NULL;
2078 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2079 destroy_workqueue(wq);
2081 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2082 remove_proc_entry(pname, NULL);
2083 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2084 remove_proc_entry(pname, NULL);
2085 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2086 remove_proc_entry(pname, NULL);
2088 /* call per device driver remove entry point */
2089 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2090 if(MptDeviceDriverHandlers[cb_idx] &&
2091 MptDeviceDriverHandlers[cb_idx]->remove) {
2092 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2096 /* Disable interrupts! */
2097 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2100 synchronize_irq(pdev->irq);
2102 /* Clear any lingering interrupt */
2103 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2105 CHIPREG_READ32(&ioc->chip->IntStatus);
2107 mpt_adapter_dispose(ioc);
2111 /**************************************************************************
2115 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2117 * mpt_suspend - Fusion MPT base driver suspend routine.
2118 * @pdev: Pointer to pci_dev structure
2119 * @state: new state to enter
2122 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2125 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2127 device_state = pci_choose_state(pdev, state);
2128 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2129 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2132 /* put ioc into READY_STATE */
2133 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2134 printk(MYIOC_s_ERR_FMT
2135 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2138 /* disable interrupts */
2139 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2142 /* Clear any lingering interrupt */
2143 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2145 free_irq(ioc->pci_irq, ioc);
2146 if (ioc->msi_enable)
2147 pci_disable_msi(ioc->pcidev);
2149 pci_save_state(pdev);
2150 pci_disable_device(pdev);
2151 pci_release_selected_regions(pdev, ioc->bars);
2152 pci_set_power_state(pdev, device_state);
2156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2158 * mpt_resume - Fusion MPT base driver resume routine.
2159 * @pdev: Pointer to pci_dev structure
2162 mpt_resume(struct pci_dev *pdev)
2164 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2165 u32 device_state = pdev->current_state;
2169 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2170 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2173 pci_set_power_state(pdev, PCI_D0);
2174 pci_enable_wake(pdev, PCI_D0, 0);
2175 pci_restore_state(pdev);
2177 err = mpt_mapresources(ioc);
2181 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2182 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2183 ioc->add_sge = &mpt_add_sge_64bit_1078;
2185 ioc->add_sge = &mpt_add_sge_64bit;
2186 ioc->add_chain = &mpt_add_chain_64bit;
2187 ioc->sg_addr_size = 8;
2190 ioc->add_sge = &mpt_add_sge;
2191 ioc->add_chain = &mpt_add_chain;
2192 ioc->sg_addr_size = 4;
2194 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2196 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2197 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2198 CHIPREG_READ32(&ioc->chip->Doorbell));
2201 * Errata workaround for SAS pci express:
2202 * Upon returning to the D0 state, the contents of the doorbell will be
2203 * stale data, and this will incorrectly signal to the host driver that
2204 * the firmware is ready to process mpt commands. The workaround is
2205 * to issue a diagnostic reset.
2207 if (ioc->bus_type == SAS && (pdev->device ==
2208 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2209 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2210 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2211 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2217 /* bring ioc to operational state */
2218 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2219 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2221 if (recovery_state != 0)
2222 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2223 "error:[%x]\n", ioc->name, recovery_state);
2225 printk(MYIOC_s_INFO_FMT
2226 "pci-resume: success\n", ioc->name);
2234 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2236 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2237 ioc->bus_type != SPI) ||
2238 (MptDriverClass[index] == MPTFC_DRIVER &&
2239 ioc->bus_type != FC) ||
2240 (MptDriverClass[index] == MPTSAS_DRIVER &&
2241 ioc->bus_type != SAS))
2242 /* make sure we only call the relevant reset handler
2245 return (MptResetHandlers[index])(ioc, reset_phase);
2248 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2250 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2251 * @ioc: Pointer to MPT adapter structure
2252 * @reason: Event word / reason
2253 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2255 * This routine performs all the steps necessary to bring the IOC
2256 * to a OPERATIONAL state.
2258 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2263 * -1 if failed to get board READY
2264 * -2 if READY but IOCFacts Failed
2265 * -3 if READY but PrimeIOCFifos Failed
2266 * -4 if READY but IOCInit Failed
2267 * -5 if failed to enable_device and/or request_selected_regions
2268 * -6 if failed to upload firmware
2271 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2273 int hard_reset_done = 0;
2274 int alt_ioc_ready = 0;
2279 int reset_alt_ioc_active = 0;
2280 int irq_allocated = 0;
2283 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2284 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2286 /* Disable reply interrupts (also blocks FreeQ) */
2287 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2291 if (ioc->alt_ioc->active ||
2292 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2293 reset_alt_ioc_active = 1;
2294 /* Disable alt-IOC's reply interrupts
2295 * (and FreeQ) for a bit
2297 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2299 ioc->alt_ioc->active = 0;
2304 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2307 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2308 if (hard_reset_done == -4) {
2309 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2312 if (reset_alt_ioc_active && ioc->alt_ioc) {
2313 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2314 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2315 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2316 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2317 ioc->alt_ioc->active = 1;
2321 printk(MYIOC_s_WARN_FMT
2322 "NOT READY WARNING!\n", ioc->name);
2328 /* hard_reset_done = 0 if a soft reset was performed
2329 * and 1 if a hard reset was performed.
2331 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2332 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2335 printk(MYIOC_s_WARN_FMT
2336 ": alt-ioc Not ready WARNING!\n",
2337 ioc->alt_ioc->name);
2340 for (ii=0; ii<5; ii++) {
2341 /* Get IOC facts! Allow 5 retries */
2342 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2348 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2349 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2351 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2352 MptDisplayIocCapabilities(ioc);
2355 if (alt_ioc_ready) {
2356 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2357 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2358 "Initial Alt IocFacts failed rc=%x\n",
2360 /* Retry - alt IOC was initialized once
2362 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2365 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2366 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2368 reset_alt_ioc_active = 0;
2369 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2370 MptDisplayIocCapabilities(ioc->alt_ioc);
2374 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2375 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2376 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2377 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2379 if (pci_enable_device(ioc->pcidev))
2381 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2387 * Device is reset now. It must have de-asserted the interrupt line
2388 * (if it was asserted) and it should be safe to register for the
2391 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2393 if (ioc->pcidev->irq) {
2394 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2395 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2398 ioc->msi_enable = 0;
2399 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2400 IRQF_SHARED, ioc->name, ioc);
2402 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2404 ioc->name, ioc->pcidev->irq);
2405 if (ioc->msi_enable)
2406 pci_disable_msi(ioc->pcidev);
2411 ioc->pci_irq = ioc->pcidev->irq;
2412 pci_set_master(ioc->pcidev); /* ?? */
2413 pci_set_drvdata(ioc->pcidev, ioc);
2414 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2415 "installed at interrupt %d\n", ioc->name,
2420 /* Prime reply & request queues!
2421 * (mucho alloc's) Must be done prior to
2422 * init as upper addresses are needed for init.
2423 * If fails, continue with alt-ioc processing
2425 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2427 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2430 /* May need to check/upload firmware & data here!
2431 * If fails, continue with alt-ioc processing
2433 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2435 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2438 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2439 printk(MYIOC_s_WARN_FMT
2440 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2441 ioc->alt_ioc->name, rc);
2443 reset_alt_ioc_active = 0;
2446 if (alt_ioc_ready) {
2447 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2449 reset_alt_ioc_active = 0;
2450 printk(MYIOC_s_WARN_FMT
2451 ": alt-ioc: (%d) init failure WARNING!\n",
2452 ioc->alt_ioc->name, rc);
2456 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2457 if (ioc->upload_fw) {
2458 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2459 "firmware upload required!\n", ioc->name));
2461 /* Controller is not operational, cannot do upload
2464 rc = mpt_do_upload(ioc, sleepFlag);
2466 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2468 * Maintain only one pointer to FW memory
2469 * so there will not be two attempt to
2470 * downloadboot onboard dual function
2471 * chips (mpt_adapter_disable,
2474 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2475 "mpt_upload: alt_%s has cached_fw=%p \n",
2476 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2477 ioc->cached_fw = NULL;
2480 printk(MYIOC_s_WARN_FMT
2481 "firmware upload failure!\n", ioc->name);
2488 /* Enable MPT base driver management of EventNotification
2489 * and EventAck handling.
2491 if ((ret == 0) && (!ioc->facts.EventState)) {
2492 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2493 "SendEventNotification\n",
2495 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2498 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2499 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2502 /* Enable! (reply interrupt) */
2503 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2506 if (rc == 0) { /* alt ioc */
2507 if (reset_alt_ioc_active && ioc->alt_ioc) {
2508 /* (re)Enable alt-IOC! (reply interrupt) */
2509 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2510 "reply irq re-enabled\n",
2511 ioc->alt_ioc->name));
2512 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2514 ioc->alt_ioc->active = 1;
2519 /* Add additional "reason" check before call to GetLanConfigPages
2520 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2521 * recursive scenario; GetLanConfigPages times out, timer expired
2522 * routine calls HardResetHandler, which calls into here again,
2523 * and we try GetLanConfigPages again...
2525 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2528 * Initialize link list for inactive raid volumes.
2530 mutex_init(&ioc->raid_data.inactive_list_mutex);
2531 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2533 switch (ioc->bus_type) {
2536 /* clear persistency table */
2537 if(ioc->facts.IOCExceptions &
2538 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2539 ret = mptbase_sas_persist_operation(ioc,
2540 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2547 mpt_findImVolumes(ioc);
2549 /* Check, and possibly reset, the coalescing value
2551 mpt_read_ioc_pg_1(ioc);
2556 if ((ioc->pfacts[0].ProtocolFlags &
2557 MPI_PORTFACTS_PROTOCOL_LAN) &&
2558 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2560 * Pre-fetch the ports LAN MAC address!
2561 * (LANPage1_t stuff)
2563 (void) GetLanConfigPages(ioc);
2564 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2565 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2566 "LanAddr = %02X:%02X:%02X"
2567 ":%02X:%02X:%02X\n",
2568 ioc->name, a[5], a[4],
2569 a[3], a[2], a[1], a[0]));
2574 /* Get NVRAM and adapter maximums from SPP 0 and 2
2576 mpt_GetScsiPortSettings(ioc, 0);
2578 /* Get version and length of SDP 1
2580 mpt_readScsiDevicePageHeaders(ioc, 0);
2584 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2585 mpt_findImVolumes(ioc);
2587 /* Check, and possibly reset, the coalescing value
2589 mpt_read_ioc_pg_1(ioc);
2591 mpt_read_ioc_pg_4(ioc);
2596 GetIoUnitPage2(ioc);
2597 mpt_get_manufacturing_pg_0(ioc);
2601 if ((ret != 0) && irq_allocated) {
2602 free_irq(ioc->pci_irq, ioc);
2603 if (ioc->msi_enable)
2604 pci_disable_msi(ioc->pcidev);
2609 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2611 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2612 * @ioc: Pointer to MPT adapter structure
2613 * @pdev: Pointer to (struct pci_dev) structure
2615 * Search for PCI bus/dev_function which matches
2616 * PCI bus/dev_function (+/-1) for newly discovered 929,
2617 * 929X, 1030 or 1035.
2619 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2620 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2623 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2625 struct pci_dev *peer=NULL;
2626 unsigned int slot = PCI_SLOT(pdev->devfn);
2627 unsigned int func = PCI_FUNC(pdev->devfn);
2628 MPT_ADAPTER *ioc_srch;
2630 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2631 " searching for devfn match on %x or %x\n",
2632 ioc->name, pci_name(pdev), pdev->bus->number,
2633 pdev->devfn, func-1, func+1));
2635 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2637 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2642 list_for_each_entry(ioc_srch, &ioc_list, list) {
2643 struct pci_dev *_pcidev = ioc_srch->pcidev;
2644 if (_pcidev == peer) {
2645 /* Paranoia checks */
2646 if (ioc->alt_ioc != NULL) {
2647 printk(MYIOC_s_WARN_FMT
2648 "Oops, already bound (%s <==> %s)!\n",
2649 ioc->name, ioc->name, ioc->alt_ioc->name);
2651 } else if (ioc_srch->alt_ioc != NULL) {
2652 printk(MYIOC_s_WARN_FMT
2653 "Oops, already bound (%s <==> %s)!\n",
2654 ioc_srch->name, ioc_srch->name,
2655 ioc_srch->alt_ioc->name);
2658 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2659 "FOUND! binding %s <==> %s\n",
2660 ioc->name, ioc->name, ioc_srch->name));
2661 ioc_srch->alt_ioc = ioc;
2662 ioc->alt_ioc = ioc_srch;
2668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2670 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2671 * @ioc: Pointer to MPT adapter structure
2674 mpt_adapter_disable(MPT_ADAPTER *ioc)
2679 if (ioc->cached_fw != NULL) {
2680 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2681 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2682 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2683 ioc->cached_fw, CAN_SLEEP)) < 0) {
2684 printk(MYIOC_s_WARN_FMT
2685 ": firmware downloadboot failure (%d)!\n",
2691 * Put the controller into ready state (if its not already)
2693 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2694 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2696 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2697 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2698 "reset failed to put ioc in ready state!\n",
2699 ioc->name, __func__);
2701 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2702 "failed!\n", ioc->name, __func__);
2706 /* Disable adapter interrupts! */
2707 synchronize_irq(ioc->pcidev->irq);
2708 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2711 /* Clear any lingering interrupt */
2712 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2713 CHIPREG_READ32(&ioc->chip->IntStatus);
2715 if (ioc->alloc != NULL) {
2717 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2718 ioc->name, ioc->alloc, ioc->alloc_sz));
2719 pci_free_consistent(ioc->pcidev, sz,
2720 ioc->alloc, ioc->alloc_dma);
2721 ioc->reply_frames = NULL;
2722 ioc->req_frames = NULL;
2724 ioc->alloc_total -= sz;
2727 if (ioc->sense_buf_pool != NULL) {
2728 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2729 pci_free_consistent(ioc->pcidev, sz,
2730 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2731 ioc->sense_buf_pool = NULL;
2732 ioc->alloc_total -= sz;
2735 if (ioc->events != NULL){
2736 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2739 ioc->alloc_total -= sz;
2742 mpt_free_fw_memory(ioc);
2744 kfree(ioc->spi_data.nvram);
2745 mpt_inactive_raid_list_free(ioc);
2746 kfree(ioc->raid_data.pIocPg2);
2747 kfree(ioc->raid_data.pIocPg3);
2748 ioc->spi_data.nvram = NULL;
2749 ioc->raid_data.pIocPg3 = NULL;
2751 if (ioc->spi_data.pIocPg4 != NULL) {
2752 sz = ioc->spi_data.IocPg4Sz;
2753 pci_free_consistent(ioc->pcidev, sz,
2754 ioc->spi_data.pIocPg4,
2755 ioc->spi_data.IocPg4_dma);
2756 ioc->spi_data.pIocPg4 = NULL;
2757 ioc->alloc_total -= sz;
2760 if (ioc->ReqToChain != NULL) {
2761 kfree(ioc->ReqToChain);
2762 kfree(ioc->RequestNB);
2763 ioc->ReqToChain = NULL;
2766 kfree(ioc->ChainToChain);
2767 ioc->ChainToChain = NULL;
2769 if (ioc->HostPageBuffer != NULL) {
2770 if((ret = mpt_host_page_access_control(ioc,
2771 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2772 printk(MYIOC_s_ERR_FMT
2773 ": %s: host page buffers free failed (%d)!\n",
2774 ioc->name, __func__, ret);
2776 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2777 "HostPageBuffer free @ %p, sz=%d bytes\n",
2778 ioc->name, ioc->HostPageBuffer,
2779 ioc->HostPageBuffer_sz));
2780 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2781 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2782 ioc->HostPageBuffer = NULL;
2783 ioc->HostPageBuffer_sz = 0;
2784 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2787 pci_set_drvdata(ioc->pcidev, NULL);
2789 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2791 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2792 * @ioc: Pointer to MPT adapter structure
2794 * This routine unregisters h/w resources and frees all alloc'd memory
2795 * associated with a MPT adapter structure.
2798 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2800 int sz_first, sz_last;
2805 sz_first = ioc->alloc_total;
2807 mpt_adapter_disable(ioc);
2809 if (ioc->pci_irq != -1) {
2810 free_irq(ioc->pci_irq, ioc);
2811 if (ioc->msi_enable)
2812 pci_disable_msi(ioc->pcidev);
2816 if (ioc->memmap != NULL) {
2817 iounmap(ioc->memmap);
2821 pci_disable_device(ioc->pcidev);
2822 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2824 #if defined(CONFIG_MTRR) && 0
2825 if (ioc->mtrr_reg > 0) {
2826 mtrr_del(ioc->mtrr_reg, 0, 0);
2827 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2831 /* Zap the adapter lookup ptr! */
2832 list_del(&ioc->list);
2834 sz_last = ioc->alloc_total;
2835 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2836 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2839 ioc->alt_ioc->alt_ioc = NULL;
2844 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2846 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2847 * @ioc: Pointer to MPT adapter structure
2850 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2854 printk(KERN_INFO "%s: ", ioc->name);
2856 printk("%s: ", ioc->prod_name);
2857 printk("Capabilities={");
2859 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2860 printk("Initiator");
2864 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2865 printk("%sTarget", i ? "," : "");
2869 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2870 printk("%sLAN", i ? "," : "");
2876 * This would probably evoke more questions than it's worth
2878 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2879 printk("%sLogBusAddr", i ? "," : "");
2887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2889 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2890 * @ioc: Pointer to MPT_ADAPTER structure
2891 * @force: Force hard KickStart of IOC
2892 * @sleepFlag: Specifies whether the process can sleep
2895 * 1 - DIAG reset and READY
2896 * 0 - READY initially OR soft reset and READY
2897 * -1 - Any failure on KickStart
2898 * -2 - Msg Unit Reset Failed
2899 * -3 - IO Unit Reset Failed
2900 * -4 - IOC owned by a PEER
2903 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2908 int hard_reset_done = 0;
2913 /* Get current [raw] IOC state */
2914 ioc_state = mpt_GetIocState(ioc, 0);
2915 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2918 * Check to see if IOC got left/stuck in doorbell handshake
2919 * grip of death. If so, hard reset the IOC.
2921 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2923 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2927 /* Is it already READY? */
2929 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2930 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2931 "IOC is in READY state\n", ioc->name));
2936 * Check to see if IOC is in FAULT state.
2938 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2940 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2942 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2943 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2947 * Hmmm... Did it get left operational?
2949 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2950 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2954 * If PCI Peer, exit.
2955 * Else, if no fault conditions are present, issue a MessageUnitReset
2956 * Else, fall through to KickStart case
2958 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2959 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2960 "whoinit 0x%x statefault %d force %d\n",
2961 ioc->name, whoinit, statefault, force));
2962 if (whoinit == MPI_WHOINIT_PCI_PEER)
2965 if ((statefault == 0 ) && (force == 0)) {
2966 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2973 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2974 if (hard_reset_done < 0)
2978 * Loop here waiting for IOC to come READY.
2981 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2983 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2984 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2986 * BIOS or previous driver load left IOC in OP state.
2987 * Reset messaging FIFOs.
2989 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2990 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2993 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2995 * Something is wrong. Try to get IOC back
2998 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2999 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
3006 printk(MYIOC_s_ERR_FMT
3007 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
3008 ioc->name, ioc_state, (int)((ii+5)/HZ));
3012 if (sleepFlag == CAN_SLEEP) {
3015 mdelay (1); /* 1 msec delay */
3020 if (statefault < 3) {
3021 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
3022 statefault == 1 ? "stuck handshake" : "IOC FAULT");
3025 return hard_reset_done;
3028 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3030 * mpt_GetIocState - Get the current state of a MPT adapter.
3031 * @ioc: Pointer to MPT_ADAPTER structure
3032 * @cooked: Request raw or cooked IOC state
3034 * Returns all IOC Doorbell register bits if cooked==0, else just the
3035 * Doorbell bits in MPI_IOC_STATE_MASK.
3038 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
3043 s = CHIPREG_READ32(&ioc->chip->Doorbell);
3044 sc = s & MPI_IOC_STATE_MASK;
3047 ioc->last_state = sc;
3049 return cooked ? sc : s;
3052 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3054 * GetIocFacts - Send IOCFacts request to MPT adapter.
3055 * @ioc: Pointer to MPT_ADAPTER structure
3056 * @sleepFlag: Specifies whether the process can sleep
3057 * @reason: If recovery, only update facts.
3059 * Returns 0 for success, non-zero for failure.
3062 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3064 IOCFacts_t get_facts;
3065 IOCFactsReply_t *facts;
3073 /* IOC *must* NOT be in RESET state! */
3074 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3075 printk(KERN_ERR MYNAM
3076 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3077 ioc->name, ioc->last_state);
3081 facts = &ioc->facts;
3083 /* Destination (reply area)... */
3084 reply_sz = sizeof(*facts);
3085 memset(facts, 0, reply_sz);
3087 /* Request area (get_facts on the stack right now!) */
3088 req_sz = sizeof(get_facts);
3089 memset(&get_facts, 0, req_sz);
3091 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3092 /* Assert: All other get_facts fields are zero! */
3094 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3095 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3096 ioc->name, req_sz, reply_sz));
3098 /* No non-zero fields in the get_facts request are greater than
3099 * 1 byte in size, so we can just fire it off as is.
3101 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3102 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3107 * Now byte swap (GRRR) the necessary fields before any further
3108 * inspection of reply contents.
3110 * But need to do some sanity checks on MsgLength (byte) field
3111 * to make sure we don't zero IOC's req_sz!
3113 /* Did we get a valid reply? */
3114 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3115 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3117 * If not been here, done that, save off first WhoInit value
3119 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3120 ioc->FirstWhoInit = facts->WhoInit;
3123 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3124 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3125 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3126 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3127 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3128 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3129 /* CHECKME! IOCStatus, IOCLogInfo */
3131 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3132 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3135 * FC f/w version changed between 1.1 and 1.2
3136 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3137 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3139 if (facts->MsgVersion < MPI_VERSION_01_02) {
3141 * Handle old FC f/w style, convert to new...
3143 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3144 facts->FWVersion.Word =
3145 ((oldv<<12) & 0xFF000000) |
3146 ((oldv<<8) & 0x000FFF00);
3148 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3150 facts->ProductID = le16_to_cpu(facts->ProductID);
3152 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3153 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3154 ioc->ir_firmware = 1;
3156 facts->CurrentHostMfaHighAddr =
3157 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3158 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3159 facts->CurrentSenseBufferHighAddr =
3160 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3161 facts->CurReplyFrameSize =
3162 le16_to_cpu(facts->CurReplyFrameSize);
3163 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3166 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3167 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3168 * to 14 in MPI-1.01.0x.
3170 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3171 facts->MsgVersion > MPI_VERSION_01_00) {
3172 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3175 facts->FWImageSize = ALIGN(facts->FWImageSize, 4);
3177 if (!facts->RequestFrameSize) {
3178 /* Something is wrong! */
3179 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3184 r = sz = facts->BlockSize;
3185 vv = ((63 / (sz * 4)) + 1) & 0x03;
3186 ioc->NB_for_64_byte_frame = vv;
3192 ioc->NBShiftFactor = shiftFactor;
3193 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3194 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3195 ioc->name, vv, shiftFactor, r));
3197 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3199 * Set values for this IOC's request & reply frame sizes,
3200 * and request & reply queue depths...
3202 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3203 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3204 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3205 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3207 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3208 ioc->name, ioc->reply_sz, ioc->reply_depth));
3209 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3210 ioc->name, ioc->req_sz, ioc->req_depth));
3212 /* Get port facts! */
3213 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3217 printk(MYIOC_s_ERR_FMT
3218 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3219 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3220 RequestFrameSize)/sizeof(u32)));
3227 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3229 * GetPortFacts - Send PortFacts request to MPT adapter.
3230 * @ioc: Pointer to MPT_ADAPTER structure
3231 * @portnum: Port number
3232 * @sleepFlag: Specifies whether the process can sleep
3234 * Returns 0 for success, non-zero for failure.
3237 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3239 PortFacts_t get_pfacts;
3240 PortFactsReply_t *pfacts;
3246 /* IOC *must* NOT be in RESET state! */
3247 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3248 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3249 ioc->name, ioc->last_state );
3253 pfacts = &ioc->pfacts[portnum];
3255 /* Destination (reply area)... */
3256 reply_sz = sizeof(*pfacts);
3257 memset(pfacts, 0, reply_sz);
3259 /* Request area (get_pfacts on the stack right now!) */
3260 req_sz = sizeof(get_pfacts);
3261 memset(&get_pfacts, 0, req_sz);
3263 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3264 get_pfacts.PortNumber = portnum;
3265 /* Assert: All other get_pfacts fields are zero! */
3267 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3268 ioc->name, portnum));
3270 /* No non-zero fields in the get_pfacts request are greater than
3271 * 1 byte in size, so we can just fire it off as is.
3273 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3274 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3278 /* Did we get a valid reply? */
3280 /* Now byte swap the necessary fields in the response. */
3281 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3282 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3283 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3284 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3285 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3286 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3287 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3288 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3289 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3291 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3293 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3294 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3297 * Place all the devices on channels
3301 if (mpt_channel_mapping) {
3302 ioc->devices_per_bus = 1;
3303 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3309 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3311 * SendIocInit - Send IOCInit request to MPT adapter.
3312 * @ioc: Pointer to MPT_ADAPTER structure
3313 * @sleepFlag: Specifies whether the process can sleep
3315 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3317 * Returns 0 for success, non-zero for failure.
3320 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3323 MPIDefaultReply_t init_reply;
3329 memset(&ioc_init, 0, sizeof(ioc_init));
3330 memset(&init_reply, 0, sizeof(init_reply));
3332 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3333 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3335 /* If we are in a recovery mode and we uploaded the FW image,
3336 * then this pointer is not NULL. Skip the upload a second time.
3337 * Set this flag if cached_fw set for either IOC.
3339 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3343 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3344 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3346 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3347 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3349 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3350 ioc->name, ioc->facts.MsgVersion));
3351 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3352 // set MsgVersion and HeaderVersion host driver was built with
3353 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3354 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3356 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3357 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3358 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3361 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3363 if (ioc->sg_addr_size == sizeof(u64)) {
3364 /* Save the upper 32-bits of the request
3365 * (reply) and sense buffers.
3367 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3368 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3370 /* Force 32-bit addressing */
3371 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3372 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3375 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3376 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3377 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3378 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3380 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3381 ioc->name, &ioc_init));
3383 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3384 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3386 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3390 /* No need to byte swap the multibyte fields in the reply
3391 * since we don't even look at its contents.
3394 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3395 ioc->name, &ioc_init));
3397 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3398 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3402 /* YIKES! SUPER IMPORTANT!!!
3403 * Poll IocState until _OPERATIONAL while IOC is doing
3404 * LoopInit and TargetDiscovery!
3407 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3408 state = mpt_GetIocState(ioc, 1);
3409 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3410 if (sleepFlag == CAN_SLEEP) {
3417 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3418 ioc->name, (int)((count+5)/HZ));
3422 state = mpt_GetIocState(ioc, 1);
3425 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3428 ioc->aen_event_read_flag=0;
3432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3434 * SendPortEnable - Send PortEnable request to MPT adapter port.
3435 * @ioc: Pointer to MPT_ADAPTER structure
3436 * @portnum: Port number to enable
3437 * @sleepFlag: Specifies whether the process can sleep
3439 * Send PortEnable to bring IOC to OPERATIONAL state.
3441 * Returns 0 for success, non-zero for failure.
3444 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3446 PortEnable_t port_enable;
3447 MPIDefaultReply_t reply_buf;
3452 /* Destination... */
3453 reply_sz = sizeof(MPIDefaultReply_t);
3454 memset(&reply_buf, 0, reply_sz);
3456 req_sz = sizeof(PortEnable_t);
3457 memset(&port_enable, 0, req_sz);
3459 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3460 port_enable.PortNumber = portnum;
3461 /* port_enable.ChainOffset = 0; */
3462 /* port_enable.MsgFlags = 0; */
3463 /* port_enable.MsgContext = 0; */
3465 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3466 ioc->name, portnum, &port_enable));
3468 /* RAID FW may take a long time to enable
3470 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3471 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3472 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3473 300 /*seconds*/, sleepFlag);
3475 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3476 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3477 30 /*seconds*/, sleepFlag);
3483 * mpt_alloc_fw_memory - allocate firmware memory
3484 * @ioc: Pointer to MPT_ADAPTER structure
3485 * @size: total FW bytes
3487 * If memory has already been allocated, the same (cached) value
3490 * Return 0 if successful, or non-zero for failure
3493 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3497 if (ioc->cached_fw) {
3498 rc = 0; /* use already allocated memory */
3501 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3502 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3503 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3507 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3508 if (!ioc->cached_fw) {
3509 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3513 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3514 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3515 ioc->alloc_total += size;
3523 * mpt_free_fw_memory - free firmware memory
3524 * @ioc: Pointer to MPT_ADAPTER structure
3526 * If alt_img is NULL, delete from ioc structure.
3527 * Else, delete a secondary image in same format.
3530 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3534 if (!ioc->cached_fw)
3537 sz = ioc->facts.FWImageSize;
3538 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3539 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3540 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3541 ioc->alloc_total -= sz;
3542 ioc->cached_fw = NULL;
3545 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3547 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3548 * @ioc: Pointer to MPT_ADAPTER structure
3549 * @sleepFlag: Specifies whether the process can sleep
3551 * Returns 0 for success, >0 for handshake failure
3552 * <0 for fw upload failure.
3554 * Remark: If bound IOC and a successful FWUpload was performed
3555 * on the bound IOC, the second image is discarded
3556 * and memory is free'd. Both channels must upload to prevent
3557 * IOC from running in degraded mode.
3560 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3562 u8 reply[sizeof(FWUploadReply_t)];
3563 FWUpload_t *prequest;
3564 FWUploadReply_t *preply;
3565 FWUploadTCSGE_t *ptcsge;
3567 int ii, sz, reply_sz;
3570 /* If the image size is 0, we are done.
3572 if ((sz = ioc->facts.FWImageSize) == 0)
3575 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3578 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3579 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3581 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3582 kzalloc(ioc->req_sz, GFP_KERNEL);
3584 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3585 "while allocating memory \n", ioc->name));
3586 mpt_free_fw_memory(ioc);
3590 preply = (FWUploadReply_t *)&reply;
3592 reply_sz = sizeof(reply);
3593 memset(preply, 0, reply_sz);
3595 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3596 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3598 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3599 ptcsge->DetailsLength = 12;
3600 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3601 ptcsge->ImageSize = cpu_to_le32(sz);
3604 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3605 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3606 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3608 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3609 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3610 ioc->facts.FWImageSize, request_size));
3611 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3613 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3614 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3616 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3617 "rc=%x \n", ioc->name, ii));
3619 cmdStatus = -EFAULT;
3621 /* Handshake transfer was complete and successful.
3622 * Check the Reply Frame.
3625 status = le16_to_cpu(preply->IOCStatus) &
3627 if (status == MPI_IOCSTATUS_SUCCESS &&
3628 ioc->facts.FWImageSize ==
3629 le32_to_cpu(preply->ActualImageSize))
3632 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3633 ioc->name, cmdStatus));
3637 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3638 "freeing image \n", ioc->name));
3639 mpt_free_fw_memory(ioc);
3646 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3648 * mpt_downloadboot - DownloadBoot code
3649 * @ioc: Pointer to MPT_ADAPTER structure
3650 * @pFwHeader: Pointer to firmware header info
3651 * @sleepFlag: Specifies whether the process can sleep
3653 * FwDownloadBoot requires Programmed IO access.
3655 * Returns 0 for success
3656 * -1 FW Image size is 0
3657 * -2 No valid cached_fw Pointer
3658 * <0 for fw upload failure.
3661 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3663 MpiExtImageHeader_t *pExtImage;
3673 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3674 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3676 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3677 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3678 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3679 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3680 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3681 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3683 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3686 if (sleepFlag == CAN_SLEEP) {
3692 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3693 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3695 for (count = 0; count < 30; count ++) {
3696 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3697 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3698 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3703 if (sleepFlag == CAN_SLEEP) {
3710 if ( count == 30 ) {
3711 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3712 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3713 ioc->name, diag0val));
3717 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3718 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3719 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3720 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3721 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3722 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3724 /* Set the DiagRwEn and Disable ARM bits */
3725 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3727 fwSize = (pFwHeader->ImageSize + 3)/4;
3728 ptrFw = (u32 *) pFwHeader;
3730 /* Write the LoadStartAddress to the DiagRw Address Register
3731 * using Programmed IO
3733 if (ioc->errata_flag_1064)
3734 pci_enable_io_access(ioc->pcidev);
3736 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3737 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3738 ioc->name, pFwHeader->LoadStartAddress));
3740 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3741 ioc->name, fwSize*4, ptrFw));
3743 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3746 nextImage = pFwHeader->NextImageHeaderOffset;
3748 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3750 load_addr = pExtImage->LoadStartAddress;
3752 fwSize = (pExtImage->ImageSize + 3) >> 2;
3753 ptrFw = (u32 *)pExtImage;
3755 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3756 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3757 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3760 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3762 nextImage = pExtImage->NextImageHeaderOffset;
3765 /* Write the IopResetVectorRegAddr */
3766 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3767 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3769 /* Write the IopResetVectorValue */
3770 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3771 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3773 /* Clear the internal flash bad bit - autoincrementing register,
3774 * so must do two writes.
3776 if (ioc->bus_type == SPI) {
3778 * 1030 and 1035 H/W errata, workaround to access
3779 * the ClearFlashBadSignatureBit
3781 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3782 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3783 diagRwData |= 0x40000000;
3784 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3785 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3787 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3788 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3789 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3790 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3793 if (sleepFlag == CAN_SLEEP) {
3800 if (ioc->errata_flag_1064)
3801 pci_disable_io_access(ioc->pcidev);
3803 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3804 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3805 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3806 ioc->name, diag0val));
3807 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3808 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3809 ioc->name, diag0val));
3810 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3812 /* Write 0xFF to reset the sequencer */
3813 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3815 if (ioc->bus_type == SAS) {
3816 ioc_state = mpt_GetIocState(ioc, 0);
3817 if ( (GetIocFacts(ioc, sleepFlag,
3818 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3819 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3820 ioc->name, ioc_state));
3825 for (count=0; count<HZ*20; count++) {
3826 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3827 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3828 "downloadboot successful! (count=%d) IocState=%x\n",
3829 ioc->name, count, ioc_state));
3830 if (ioc->bus_type == SAS) {
3833 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3834 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3835 "downloadboot: SendIocInit failed\n",
3839 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3840 "downloadboot: SendIocInit successful\n",
3844 if (sleepFlag == CAN_SLEEP) {
3850 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3851 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3855 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3857 * KickStart - Perform hard reset of MPT adapter.
3858 * @ioc: Pointer to MPT_ADAPTER structure
3859 * @force: Force hard reset
3860 * @sleepFlag: Specifies whether the process can sleep
3862 * This routine places MPT adapter in diagnostic mode via the
3863 * WriteSequence register, and then performs a hard reset of adapter
3864 * via the Diagnostic register.
3866 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3867 * or NO_SLEEP (interrupt thread, use mdelay)
3868 * force - 1 if doorbell active, board fault state
3869 * board operational, IOC_RECOVERY or
3870 * IOC_BRINGUP and there is an alt_ioc.
3874 * 1 - hard reset, READY
3875 * 0 - no reset due to History bit, READY
3876 * -1 - no reset due to History bit but not READY
3877 * OR reset but failed to come READY
3878 * -2 - no reset, could not enter DIAG mode
3879 * -3 - reset but bad FW bit
3882 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3884 int hard_reset_done = 0;
3888 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3889 if (ioc->bus_type == SPI) {
3890 /* Always issue a Msg Unit Reset first. This will clear some
3891 * SCSI bus hang conditions.
3893 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3895 if (sleepFlag == CAN_SLEEP) {
3902 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3903 if (hard_reset_done < 0)
3904 return hard_reset_done;
3906 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3909 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3910 for (cnt=0; cnt<cntdn; cnt++) {
3911 ioc_state = mpt_GetIocState(ioc, 1);
3912 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3913 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3915 return hard_reset_done;
3917 if (sleepFlag == CAN_SLEEP) {
3924 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3925 ioc->name, mpt_GetIocState(ioc, 0)));
3929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3931 * mpt_diag_reset - Perform hard reset of the adapter.
3932 * @ioc: Pointer to MPT_ADAPTER structure
3933 * @ignore: Set if to honor and clear to ignore
3934 * the reset history bit
3935 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3936 * else set to NO_SLEEP (use mdelay instead)
3938 * This routine places the adapter in diagnostic mode via the
3939 * WriteSequence register and then performs a hard reset of adapter
3940 * via the Diagnostic register. Adapter should be in ready state
3941 * upon successful completion.
3943 * Returns: 1 hard reset successful
3944 * 0 no reset performed because reset history bit set
3945 * -2 enabling diagnostic mode failed
3946 * -3 diagnostic reset failed
3949 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3953 int hard_reset_done = 0;
3956 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3959 /* Clear any existing interrupts */
3960 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3962 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3967 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3968 "address=%p\n", ioc->name, __func__,
3969 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3970 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3971 if (sleepFlag == CAN_SLEEP)
3977 * Call each currently registered protocol IOC reset handler
3978 * with pre-reset indication.
3979 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3980 * MptResetHandlers[] registered yet.
3982 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3983 if (MptResetHandlers[cb_idx])
3984 (*(MptResetHandlers[cb_idx]))(ioc,
3988 for (count = 0; count < 60; count ++) {
3989 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3990 doorbell &= MPI_IOC_STATE_MASK;
3992 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3993 "looking for READY STATE: doorbell=%x"
3995 ioc->name, doorbell, count));
3997 if (doorbell == MPI_IOC_STATE_READY) {
4002 if (sleepFlag == CAN_SLEEP)
4010 /* Use "Diagnostic reset" method! (only thing available!) */
4011 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4013 if (ioc->debug_level & MPT_DEBUG) {
4015 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4016 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
4017 ioc->name, diag0val, diag1val));
4020 /* Do the reset if we are told to ignore the reset history
4021 * or if the reset history is 0
4023 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
4024 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4025 /* Write magic sequence to WriteSequence register
4026 * Loop until in diagnostic mode
4028 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4029 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4030 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4031 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4032 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4033 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4036 if (sleepFlag == CAN_SLEEP) {
4044 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4045 ioc->name, diag0val);
4050 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4052 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4053 ioc->name, diag0val));
4056 if (ioc->debug_level & MPT_DEBUG) {
4058 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4059 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4060 ioc->name, diag0val, diag1val));
4063 * Disable the ARM (Bug fix)
4066 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4070 * Now hit the reset bit in the Diagnostic register
4071 * (THE BIG HAMMER!) (Clears DRWE bit).
4073 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4074 hard_reset_done = 1;
4075 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4079 * Call each currently registered protocol IOC reset handler
4080 * with pre-reset indication.
4081 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4082 * MptResetHandlers[] registered yet.
4084 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4085 if (MptResetHandlers[cb_idx]) {
4086 mpt_signal_reset(cb_idx,
4087 ioc, MPT_IOC_PRE_RESET);
4089 mpt_signal_reset(cb_idx,
4090 ioc->alt_ioc, MPT_IOC_PRE_RESET);
4096 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4097 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4098 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4102 /* If the DownloadBoot operation fails, the
4103 * IOC will be left unusable. This is a fatal error
4104 * case. _diag_reset will return < 0
4106 for (count = 0; count < 30; count ++) {
4107 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4108 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4112 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4113 ioc->name, diag0val, count));
4115 if (sleepFlag == CAN_SLEEP) {
4121 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4122 printk(MYIOC_s_WARN_FMT
4123 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4127 /* Wait for FW to reload and for board
4128 * to go to the READY state.
4129 * Maximum wait is 60 seconds.
4130 * If fail, no error will check again
4131 * with calling program.
4133 for (count = 0; count < 60; count ++) {
4134 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4135 doorbell &= MPI_IOC_STATE_MASK;
4137 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4138 "looking for READY STATE: doorbell=%x"
4139 " count=%d\n", ioc->name, doorbell, count));
4141 if (doorbell == MPI_IOC_STATE_READY) {
4146 if (sleepFlag == CAN_SLEEP) {
4153 if (doorbell != MPI_IOC_STATE_READY)
4154 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4155 "after reset! IocState=%x", ioc->name,
4160 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4161 if (ioc->debug_level & MPT_DEBUG) {
4163 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4164 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4165 ioc->name, diag0val, diag1val));
4168 /* Clear RESET_HISTORY bit! Place board in the
4169 * diagnostic mode to update the diag register.
4171 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4173 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4174 /* Write magic sequence to WriteSequence register
4175 * Loop until in diagnostic mode
4177 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4178 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4179 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4180 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4181 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4182 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4185 if (sleepFlag == CAN_SLEEP) {
4193 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4194 ioc->name, diag0val);
4197 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4199 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4200 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4201 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4202 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4203 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4207 /* Disable Diagnostic Mode
4209 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4211 /* Check FW reload status flags.
4213 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4214 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4215 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4216 ioc->name, diag0val);
4220 if (ioc->debug_level & MPT_DEBUG) {
4222 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4223 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4224 ioc->name, diag0val, diag1val));
4228 * Reset flag that says we've enabled event notification
4230 ioc->facts.EventState = 0;
4233 ioc->alt_ioc->facts.EventState = 0;
4235 return hard_reset_done;
4238 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4240 * SendIocReset - Send IOCReset request to MPT adapter.
4241 * @ioc: Pointer to MPT_ADAPTER structure
4242 * @reset_type: reset type, expected values are
4243 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4244 * @sleepFlag: Specifies whether the process can sleep
4246 * Send IOCReset request to the MPT adapter.
4248 * Returns 0 for success, non-zero for failure.
4251 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4257 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4258 ioc->name, reset_type));
4259 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4260 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4263 /* FW ACK'd request, wait for READY state
4266 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4268 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4272 if (sleepFlag != CAN_SLEEP)
4275 printk(MYIOC_s_ERR_FMT
4276 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4277 ioc->name, state, (int)((count+5)/HZ));
4281 if (sleepFlag == CAN_SLEEP) {
4284 mdelay (1); /* 1 msec delay */
4289 * Cleanup all event stuff for this IOC; re-issue EventNotification
4290 * request if needed.
4292 if (ioc->facts.Function)
4293 ioc->facts.EventState = 0;
4298 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4300 * initChainBuffers - Allocate memory for and initialize chain buffers
4301 * @ioc: Pointer to MPT_ADAPTER structure
4303 * Allocates memory for and initializes chain buffers,
4304 * chain buffer control arrays and spinlock.
4307 initChainBuffers(MPT_ADAPTER *ioc)
4310 int sz, ii, num_chain;
4311 int scale, num_sge, numSGE;
4313 /* ReqToChain size must equal the req_depth
4316 if (ioc->ReqToChain == NULL) {
4317 sz = ioc->req_depth * sizeof(int);
4318 mem = kmalloc(sz, GFP_ATOMIC);
4322 ioc->ReqToChain = (int *) mem;
4323 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4324 ioc->name, mem, sz));
4325 mem = kmalloc(sz, GFP_ATOMIC);
4329 ioc->RequestNB = (int *) mem;
4330 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4331 ioc->name, mem, sz));
4333 for (ii = 0; ii < ioc->req_depth; ii++) {
4334 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4337 /* ChainToChain size must equal the total number
4338 * of chain buffers to be allocated.
4341 * Calculate the number of chain buffers needed(plus 1) per I/O
4342 * then multiply the maximum number of simultaneous cmds
4344 * num_sge = num sge in request frame + last chain buffer
4345 * scale = num sge per chain buffer if no chain element
4347 scale = ioc->req_sz / ioc->SGE_size;
4348 if (ioc->sg_addr_size == sizeof(u64))
4349 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4351 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4353 if (ioc->sg_addr_size == sizeof(u64)) {
4354 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4355 (ioc->req_sz - 60) / ioc->SGE_size;
4357 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4358 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4360 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4361 ioc->name, num_sge, numSGE));
4363 if (ioc->bus_type == FC) {
4364 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4365 numSGE = MPT_SCSI_FC_SG_DEPTH;
4367 if (numSGE > MPT_SCSI_SG_DEPTH)
4368 numSGE = MPT_SCSI_SG_DEPTH;
4372 while (numSGE - num_sge > 0) {
4374 num_sge += (scale - 1);
4378 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4379 ioc->name, numSGE, num_sge, num_chain));
4381 if (ioc->bus_type == SPI)
4382 num_chain *= MPT_SCSI_CAN_QUEUE;
4383 else if (ioc->bus_type == SAS)
4384 num_chain *= MPT_SAS_CAN_QUEUE;
4386 num_chain *= MPT_FC_CAN_QUEUE;
4388 ioc->num_chain = num_chain;
4390 sz = num_chain * sizeof(int);
4391 if (ioc->ChainToChain == NULL) {
4392 mem = kmalloc(sz, GFP_ATOMIC);
4396 ioc->ChainToChain = (int *) mem;
4397 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4398 ioc->name, mem, sz));
4400 mem = (u8 *) ioc->ChainToChain;
4402 memset(mem, 0xFF, sz);
4406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4408 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4409 * @ioc: Pointer to MPT_ADAPTER structure
4411 * This routine allocates memory for the MPT reply and request frame
4412 * pools (if necessary), and primes the IOC reply FIFO with
4415 * Returns 0 for success, non-zero for failure.
4418 PrimeIocFifos(MPT_ADAPTER *ioc)
4421 unsigned long flags;
4422 dma_addr_t alloc_dma;
4424 int i, reply_sz, sz, total_size, num_chain;
4429 /* Prime reply FIFO... */
4431 if (ioc->reply_frames == NULL) {
4432 if ( (num_chain = initChainBuffers(ioc)) < 0)
4435 * 1078 errata workaround for the 36GB limitation
4437 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4438 ioc->dma_mask > DMA_BIT_MASK(35)) {
4439 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4440 && !pci_set_consistent_dma_mask(ioc->pcidev,
4441 DMA_BIT_MASK(32))) {
4442 dma_mask = DMA_BIT_MASK(35);
4443 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4444 "setting 35 bit addressing for "
4445 "Request/Reply/Chain and Sense Buffers\n",
4448 /*Reseting DMA mask to 64 bit*/
4449 pci_set_dma_mask(ioc->pcidev,
4451 pci_set_consistent_dma_mask(ioc->pcidev,
4454 printk(MYIOC_s_ERR_FMT
4455 "failed setting 35 bit addressing for "
4456 "Request/Reply/Chain and Sense Buffers\n",
4462 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4463 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4464 ioc->name, ioc->reply_sz, ioc->reply_depth));
4465 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4466 ioc->name, reply_sz, reply_sz));
4468 sz = (ioc->req_sz * ioc->req_depth);
4469 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4470 ioc->name, ioc->req_sz, ioc->req_depth));
4471 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4472 ioc->name, sz, sz));
4475 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4476 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4477 ioc->name, ioc->req_sz, num_chain));
4478 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4479 ioc->name, sz, sz, num_chain));
4482 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4484 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4489 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4490 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4492 memset(mem, 0, total_size);
4493 ioc->alloc_total += total_size;
4495 ioc->alloc_dma = alloc_dma;
4496 ioc->alloc_sz = total_size;
4497 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4498 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4500 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4501 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4503 alloc_dma += reply_sz;
4506 /* Request FIFO - WE manage this! */
4508 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4509 ioc->req_frames_dma = alloc_dma;
4511 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4512 ioc->name, mem, (void *)(ulong)alloc_dma));
4514 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4516 #if defined(CONFIG_MTRR) && 0
4518 * Enable Write Combining MTRR for IOC's memory region.
4519 * (at least as much as we can; "size and base must be
4520 * multiples of 4 kiB"
4522 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4524 MTRR_TYPE_WRCOMB, 1);
4525 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4526 ioc->name, ioc->req_frames_dma, sz));
4529 for (i = 0; i < ioc->req_depth; i++) {
4530 alloc_dma += ioc->req_sz;
4534 ioc->ChainBuffer = mem;
4535 ioc->ChainBufferDMA = alloc_dma;
4537 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4538 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4540 /* Initialize the free chain Q.
4543 INIT_LIST_HEAD(&ioc->FreeChainQ);
4545 /* Post the chain buffers to the FreeChainQ.
4547 mem = (u8 *)ioc->ChainBuffer;
4548 for (i=0; i < num_chain; i++) {
4549 mf = (MPT_FRAME_HDR *) mem;
4550 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4554 /* Initialize Request frames linked list
4556 alloc_dma = ioc->req_frames_dma;
4557 mem = (u8 *) ioc->req_frames;
4559 spin_lock_irqsave(&ioc->FreeQlock, flags);
4560 INIT_LIST_HEAD(&ioc->FreeQ);
4561 for (i = 0; i < ioc->req_depth; i++) {
4562 mf = (MPT_FRAME_HDR *) mem;
4564 /* Queue REQUESTs *internally*! */
4565 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4569 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4571 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4572 ioc->sense_buf_pool =
4573 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4574 if (ioc->sense_buf_pool == NULL) {
4575 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4580 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4581 ioc->alloc_total += sz;
4582 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4583 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4587 /* Post Reply frames to FIFO
4589 alloc_dma = ioc->alloc_dma;
4590 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4591 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4593 for (i = 0; i < ioc->reply_depth; i++) {
4594 /* Write each address to the IOC! */
4595 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4596 alloc_dma += ioc->reply_sz;
4599 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4600 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4602 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4603 "restoring 64 bit addressing\n", ioc->name));
4609 if (ioc->alloc != NULL) {
4611 pci_free_consistent(ioc->pcidev,
4613 ioc->alloc, ioc->alloc_dma);
4614 ioc->reply_frames = NULL;
4615 ioc->req_frames = NULL;
4616 ioc->alloc_total -= sz;
4618 if (ioc->sense_buf_pool != NULL) {
4619 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4620 pci_free_consistent(ioc->pcidev,
4622 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4623 ioc->sense_buf_pool = NULL;
4626 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4627 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4629 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4630 "restoring 64 bit addressing\n", ioc->name));
4635 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4637 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4638 * from IOC via doorbell handshake method.
4639 * @ioc: Pointer to MPT_ADAPTER structure
4640 * @reqBytes: Size of the request in bytes
4641 * @req: Pointer to MPT request frame
4642 * @replyBytes: Expected size of the reply in bytes
4643 * @u16reply: Pointer to area where reply should be written
4644 * @maxwait: Max wait time for a reply (in seconds)
4645 * @sleepFlag: Specifies whether the process can sleep
4647 * NOTES: It is the callers responsibility to byte-swap fields in the
4648 * request which are greater than 1 byte in size. It is also the
4649 * callers responsibility to byte-swap response fields which are
4650 * greater than 1 byte in size.
4652 * Returns 0 for success, non-zero for failure.
4655 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4656 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4658 MPIDefaultReply_t *mptReply;
4663 * Get ready to cache a handshake reply
4665 ioc->hs_reply_idx = 0;
4666 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4667 mptReply->MsgLength = 0;
4670 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4671 * then tell IOC that we want to handshake a request of N words.
4672 * (WRITE u32val to Doorbell reg).
4674 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4675 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4676 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4677 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4680 * Wait for IOC's doorbell handshake int
4682 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4685 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4686 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4688 /* Read doorbell and check for active bit */
4689 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4693 * Clear doorbell int (WRITE 0 to IntStatus reg),
4694 * then wait for IOC to ACKnowledge that it's ready for
4695 * our handshake request.
4697 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4698 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4703 u8 *req_as_bytes = (u8 *) req;
4706 * Stuff request words via doorbell handshake,
4707 * with ACK from IOC for each.
4709 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4710 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4711 (req_as_bytes[(ii*4) + 1] << 8) |
4712 (req_as_bytes[(ii*4) + 2] << 16) |
4713 (req_as_bytes[(ii*4) + 3] << 24));
4715 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4716 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4720 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4721 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4723 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4724 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4727 * Wait for completion of doorbell handshake reply from the IOC
4729 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4732 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4733 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4736 * Copy out the cached reply...
4738 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4739 u16reply[ii] = ioc->hs_reply[ii];
4747 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4749 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4750 * @ioc: Pointer to MPT_ADAPTER structure
4751 * @howlong: How long to wait (in seconds)
4752 * @sleepFlag: Specifies whether the process can sleep
4754 * This routine waits (up to ~2 seconds max) for IOC doorbell
4755 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4756 * bit in its IntStatus register being clear.
4758 * Returns a negative value on failure, else wait loop count.
4761 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4767 cntdn = 1000 * howlong;
4769 if (sleepFlag == CAN_SLEEP) {
4772 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4773 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4780 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4781 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4788 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4793 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4794 ioc->name, count, intstat);
4798 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4800 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4801 * @ioc: Pointer to MPT_ADAPTER structure
4802 * @howlong: How long to wait (in seconds)
4803 * @sleepFlag: Specifies whether the process can sleep
4805 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4806 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4808 * Returns a negative value on failure, else wait loop count.
4811 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4817 cntdn = 1000 * howlong;
4818 if (sleepFlag == CAN_SLEEP) {
4820 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4821 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4828 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4829 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4837 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4838 ioc->name, count, howlong));
4842 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4843 ioc->name, count, intstat);
4847 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4849 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4850 * @ioc: Pointer to MPT_ADAPTER structure
4851 * @howlong: How long to wait (in seconds)
4852 * @sleepFlag: Specifies whether the process can sleep
4854 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4855 * Reply is cached to IOC private area large enough to hold a maximum
4856 * of 128 bytes of reply data.
4858 * Returns a negative value on failure, else size of reply in WORDS.
4861 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4866 u16 *hs_reply = ioc->hs_reply;
4867 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4870 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4873 * Get first two u16's so we can look at IOC's intended reply MsgLength
4876 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4879 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4880 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4881 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4884 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4885 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4889 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4890 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4891 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4894 * If no error (and IOC said MsgLength is > 0), piece together
4895 * reply 16 bits at a time.
4897 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4898 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4900 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4901 /* don't overflow our IOC hs_reply[] buffer! */
4902 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4903 hs_reply[u16cnt] = hword;
4904 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4907 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4909 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4912 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4917 else if (u16cnt != (2 * mptReply->MsgLength)) {
4920 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4925 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4926 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4928 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4929 ioc->name, t, u16cnt/2));
4933 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4935 * GetLanConfigPages - Fetch LANConfig pages.
4936 * @ioc: Pointer to MPT_ADAPTER structure
4938 * Return: 0 for success
4939 * -ENOMEM if no memory available
4940 * -EPERM if not allowed due to ISR context
4941 * -EAGAIN if no msg frames currently available
4942 * -EFAULT for non-successful reply or no reply (timeout)
4945 GetLanConfigPages(MPT_ADAPTER *ioc)
4947 ConfigPageHeader_t hdr;
4949 LANPage0_t *ppage0_alloc;
4950 dma_addr_t page0_dma;
4951 LANPage1_t *ppage1_alloc;
4952 dma_addr_t page1_dma;
4957 /* Get LAN Page 0 header */
4958 hdr.PageVersion = 0;
4961 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4962 cfg.cfghdr.hdr = &hdr;
4964 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4969 if ((rc = mpt_config(ioc, &cfg)) != 0)
4972 if (hdr.PageLength > 0) {
4973 data_sz = hdr.PageLength * 4;
4974 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4977 memset((u8 *)ppage0_alloc, 0, data_sz);
4978 cfg.physAddr = page0_dma;
4979 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4981 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4983 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4984 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4988 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4991 * Normalize endianness of structure data,
4992 * by byte-swapping all > 1 byte fields!
5001 /* Get LAN Page 1 header */
5002 hdr.PageVersion = 0;
5005 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
5006 cfg.cfghdr.hdr = &hdr;
5008 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5012 if ((rc = mpt_config(ioc, &cfg)) != 0)
5015 if (hdr.PageLength == 0)
5018 data_sz = hdr.PageLength * 4;
5020 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
5022 memset((u8 *)ppage1_alloc, 0, data_sz);
5023 cfg.physAddr = page1_dma;
5024 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5026 if ((rc = mpt_config(ioc, &cfg)) == 0) {
5028 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
5029 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
5032 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
5035 * Normalize endianness of structure data,
5036 * by byte-swapping all > 1 byte fields!
5044 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5046 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5047 * @ioc: Pointer to MPT_ADAPTER structure
5048 * @persist_opcode: see below
5050 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5051 * devices not currently present.
5052 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5054 * NOTE: Don't use not this function during interrupt time.
5056 * Returns 0 for success, non-zero error
5059 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5061 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5063 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5064 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5065 MPT_FRAME_HDR *mf = NULL;
5066 MPIHeader_t *mpi_hdr;
5068 unsigned long timeleft;
5070 mutex_lock(&ioc->mptbase_cmds.mutex);
5072 /* init the internal cmd struct */
5073 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5074 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5076 /* insure garbage is not sent to fw */
5077 switch(persist_opcode) {
5079 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5080 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5088 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5089 __func__, persist_opcode);
5091 /* Get a MF for this command.
5093 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5094 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5099 mpi_hdr = (MPIHeader_t *) mf;
5100 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5101 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5102 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5103 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5104 sasIoUnitCntrReq->Operation = persist_opcode;
5106 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5107 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5108 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5110 printk(KERN_DEBUG "%s: failed\n", __func__);
5111 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5114 printk(MYIOC_s_WARN_FMT
5115 "Issuing Reset from %s!!, doorbell=0x%08x\n",
5116 ioc->name, __func__, mpt_GetIocState(ioc, 0));
5117 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5118 mpt_free_msg_frame(ioc, mf);
5123 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5128 sasIoUnitCntrReply =
5129 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5130 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5131 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5132 __func__, sasIoUnitCntrReply->IOCStatus,
5133 sasIoUnitCntrReply->IOCLogInfo);
5134 printk(KERN_DEBUG "%s: failed\n", __func__);
5137 printk(KERN_DEBUG "%s: success\n", __func__);
5140 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5141 mutex_unlock(&ioc->mptbase_cmds.mutex);
5145 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5148 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5149 MpiEventDataRaid_t * pRaidEventData)
5158 volume = pRaidEventData->VolumeID;
5159 reason = pRaidEventData->ReasonCode;
5160 disk = pRaidEventData->PhysDiskNum;
5161 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5162 flags = (status >> 0) & 0xff;
5163 state = (status >> 8) & 0xff;
5165 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5169 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5170 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5171 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5172 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5173 ioc->name, disk, volume);
5175 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5180 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5181 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5185 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5187 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5191 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5192 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5196 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5197 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5199 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5201 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5203 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5206 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5208 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5209 ? ", quiesced" : "",
5210 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5211 ? ", resync in progress" : "" );
5214 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5215 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5219 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5220 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5224 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5225 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5229 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5230 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5234 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5235 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5237 state == MPI_PHYSDISK0_STATUS_ONLINE
5239 : state == MPI_PHYSDISK0_STATUS_MISSING
5241 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5243 : state == MPI_PHYSDISK0_STATUS_FAILED
5245 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5247 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5248 ? "offline requested"
5249 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5250 ? "failed requested"
5251 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5254 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5255 ? ", out of sync" : "",
5256 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5257 ? ", quiesced" : "" );
5260 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5261 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5265 case MPI_EVENT_RAID_RC_SMART_DATA:
5266 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5267 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5270 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5271 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5279 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5280 * @ioc: Pointer to MPT_ADAPTER structure
5282 * Returns: 0 for success
5283 * -ENOMEM if no memory available
5284 * -EPERM if not allowed due to ISR context
5285 * -EAGAIN if no msg frames currently available
5286 * -EFAULT for non-successful reply or no reply (timeout)
5289 GetIoUnitPage2(MPT_ADAPTER *ioc)
5291 ConfigPageHeader_t hdr;
5293 IOUnitPage2_t *ppage_alloc;
5294 dma_addr_t page_dma;
5298 /* Get the page header */
5299 hdr.PageVersion = 0;
5302 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5303 cfg.cfghdr.hdr = &hdr;
5305 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5310 if ((rc = mpt_config(ioc, &cfg)) != 0)
5313 if (hdr.PageLength == 0)
5316 /* Read the config page */
5317 data_sz = hdr.PageLength * 4;
5319 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5321 memset((u8 *)ppage_alloc, 0, data_sz);
5322 cfg.physAddr = page_dma;
5323 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5325 /* If Good, save data */
5326 if ((rc = mpt_config(ioc, &cfg)) == 0)
5327 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5329 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5335 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5337 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5338 * @ioc: Pointer to a Adapter Strucutre
5339 * @portnum: IOC port number
5341 * Return: -EFAULT if read of config page header fails
5343 * If read of SCSI Port Page 0 fails,
5344 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5345 * Adapter settings: async, narrow
5347 * If read of SCSI Port Page 2 fails,
5348 * Adapter settings valid
5349 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5354 * CHECK - what type of locking mechanisms should be used????
5357 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5362 ConfigPageHeader_t header;
5368 if (!ioc->spi_data.nvram) {
5371 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5372 mem = kmalloc(sz, GFP_ATOMIC);
5376 ioc->spi_data.nvram = (int *) mem;
5378 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5379 ioc->name, ioc->spi_data.nvram, sz));
5382 /* Invalidate NVRAM information
5384 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5385 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5388 /* Read SPP0 header, allocate memory, then read page.
5390 header.PageVersion = 0;
5391 header.PageLength = 0;
5392 header.PageNumber = 0;
5393 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5394 cfg.cfghdr.hdr = &header;
5396 cfg.pageAddr = portnum;
5397 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5399 cfg.timeout = 0; /* use default */
5400 if (mpt_config(ioc, &cfg) != 0)
5403 if (header.PageLength > 0) {
5404 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5406 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5407 cfg.physAddr = buf_dma;
5408 if (mpt_config(ioc, &cfg) != 0) {
5409 ioc->spi_data.maxBusWidth = MPT_NARROW;
5410 ioc->spi_data.maxSyncOffset = 0;
5411 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5412 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5414 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5415 "Unable to read PortPage0 minSyncFactor=%x\n",
5416 ioc->name, ioc->spi_data.minSyncFactor));
5418 /* Save the Port Page 0 data
5420 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5421 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5422 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5424 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5425 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5426 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5427 "noQas due to Capabilities=%x\n",
5428 ioc->name, pPP0->Capabilities));
5430 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5431 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5433 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5434 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5435 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5436 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5437 "PortPage0 minSyncFactor=%x\n",
5438 ioc->name, ioc->spi_data.minSyncFactor));
5440 ioc->spi_data.maxSyncOffset = 0;
5441 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5444 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5446 /* Update the minSyncFactor based on bus type.
5448 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5449 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5451 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5452 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5453 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5454 "HVD or SE detected, minSyncFactor=%x\n",
5455 ioc->name, ioc->spi_data.minSyncFactor));
5460 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5465 /* SCSI Port Page 2 - Read the header then the page.
5467 header.PageVersion = 0;
5468 header.PageLength = 0;
5469 header.PageNumber = 2;
5470 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5471 cfg.cfghdr.hdr = &header;
5473 cfg.pageAddr = portnum;
5474 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5476 if (mpt_config(ioc, &cfg) != 0)
5479 if (header.PageLength > 0) {
5480 /* Allocate memory and read SCSI Port Page 2
5482 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5484 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5485 cfg.physAddr = buf_dma;
5486 if (mpt_config(ioc, &cfg) != 0) {
5487 /* Nvram data is left with INVALID mark
5490 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5492 /* This is an ATTO adapter, read Page2 accordingly
5494 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5495 ATTODeviceInfo_t *pdevice = NULL;
5498 /* Save the Port Page 2 data
5499 * (reformat into a 32bit quantity)
5501 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5502 pdevice = &pPP2->DeviceSettings[ii];
5503 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5506 /* Translate ATTO device flags to LSI format
5508 if (ATTOFlags & ATTOFLAG_DISC)
5509 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5510 if (ATTOFlags & ATTOFLAG_ID_ENB)
5511 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5512 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5513 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5514 if (ATTOFlags & ATTOFLAG_TAGGED)
5515 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5516 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5517 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5519 data = (data << 16) | (pdevice->Period << 8) | 10;
5520 ioc->spi_data.nvram[ii] = data;
5523 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5524 MpiDeviceInfo_t *pdevice = NULL;
5527 * Save "Set to Avoid SCSI Bus Resets" flag
5529 ioc->spi_data.bus_reset =
5530 (le32_to_cpu(pPP2->PortFlags) &
5531 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5534 /* Save the Port Page 2 data
5535 * (reformat into a 32bit quantity)
5537 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5538 ioc->spi_data.PortFlags = data;
5539 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5540 pdevice = &pPP2->DeviceSettings[ii];
5541 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5542 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5543 ioc->spi_data.nvram[ii] = data;
5547 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5551 /* Update Adapter limits with those from NVRAM
5552 * Comment: Don't need to do this. Target performance
5553 * parameters will never exceed the adapters limits.
5559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5561 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5562 * @ioc: Pointer to a Adapter Strucutre
5563 * @portnum: IOC port number
5565 * Return: -EFAULT if read of config page header fails
5569 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5572 ConfigPageHeader_t header;
5574 /* Read the SCSI Device Page 1 header
5576 header.PageVersion = 0;
5577 header.PageLength = 0;
5578 header.PageNumber = 1;
5579 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5580 cfg.cfghdr.hdr = &header;
5582 cfg.pageAddr = portnum;
5583 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5586 if (mpt_config(ioc, &cfg) != 0)
5589 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5590 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5592 header.PageVersion = 0;
5593 header.PageLength = 0;
5594 header.PageNumber = 0;
5595 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5596 if (mpt_config(ioc, &cfg) != 0)
5599 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5600 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5602 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5603 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5605 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5606 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5611 * mpt_inactive_raid_list_free - This clears this link list.
5612 * @ioc : pointer to per adapter structure
5615 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5617 struct inactive_raid_component_info *component_info, *pNext;
5619 if (list_empty(&ioc->raid_data.inactive_list))
5622 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5623 list_for_each_entry_safe(component_info, pNext,
5624 &ioc->raid_data.inactive_list, list) {
5625 list_del(&component_info->list);
5626 kfree(component_info);
5628 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5632 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5634 * @ioc : pointer to per adapter structure
5635 * @channel : volume channel
5636 * @id : volume target id
5639 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5642 ConfigPageHeader_t hdr;
5643 dma_addr_t dma_handle;
5644 pRaidVolumePage0_t buffer = NULL;
5646 RaidPhysDiskPage0_t phys_disk;
5647 struct inactive_raid_component_info *component_info;
5648 int handle_inactive_volumes;
5650 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5651 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5652 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5653 cfg.pageAddr = (channel << 8) + id;
5654 cfg.cfghdr.hdr = &hdr;
5655 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5657 if (mpt_config(ioc, &cfg) != 0)
5660 if (!hdr.PageLength)
5663 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5669 cfg.physAddr = dma_handle;
5670 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5672 if (mpt_config(ioc, &cfg) != 0)
5675 if (!buffer->NumPhysDisks)
5678 handle_inactive_volumes =
5679 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5680 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5681 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5682 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5684 if (!handle_inactive_volumes)
5687 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5688 for (i = 0; i < buffer->NumPhysDisks; i++) {
5689 if(mpt_raid_phys_disk_pg0(ioc,
5690 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5693 if ((component_info = kmalloc(sizeof (*component_info),
5694 GFP_KERNEL)) == NULL)
5697 component_info->volumeID = id;
5698 component_info->volumeBus = channel;
5699 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5700 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5701 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5702 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5704 list_add_tail(&component_info->list,
5705 &ioc->raid_data.inactive_list);
5707 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5711 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5716 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5717 * @ioc: Pointer to a Adapter Structure
5718 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5719 * @phys_disk: requested payload data returned
5723 * -EFAULT if read of config page header fails or data pointer not NULL
5724 * -ENOMEM if pci_alloc failed
5727 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5728 RaidPhysDiskPage0_t *phys_disk)
5731 ConfigPageHeader_t hdr;
5732 dma_addr_t dma_handle;
5733 pRaidPhysDiskPage0_t buffer = NULL;
5736 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5737 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5738 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5740 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5741 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5742 cfg.cfghdr.hdr = &hdr;
5744 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5746 if (mpt_config(ioc, &cfg) != 0) {
5751 if (!hdr.PageLength) {
5756 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5764 cfg.physAddr = dma_handle;
5765 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5766 cfg.pageAddr = phys_disk_num;
5768 if (mpt_config(ioc, &cfg) != 0) {
5774 memcpy(phys_disk, buffer, sizeof(*buffer));
5775 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5780 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5787 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5788 * @ioc: Pointer to a Adapter Structure
5789 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5792 * returns number paths
5795 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5798 ConfigPageHeader_t hdr;
5799 dma_addr_t dma_handle;
5800 pRaidPhysDiskPage1_t buffer = NULL;
5803 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5804 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5806 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5807 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5809 cfg.cfghdr.hdr = &hdr;
5811 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5813 if (mpt_config(ioc, &cfg) != 0) {
5818 if (!hdr.PageLength) {
5823 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5831 cfg.physAddr = dma_handle;
5832 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5833 cfg.pageAddr = phys_disk_num;
5835 if (mpt_config(ioc, &cfg) != 0) {
5840 rc = buffer->NumPhysDiskPaths;
5844 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5849 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5852 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5853 * @ioc: Pointer to a Adapter Structure
5854 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5855 * @phys_disk: requested payload data returned
5859 * -EFAULT if read of config page header fails or data pointer not NULL
5860 * -ENOMEM if pci_alloc failed
5863 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5864 RaidPhysDiskPage1_t *phys_disk)
5867 ConfigPageHeader_t hdr;
5868 dma_addr_t dma_handle;
5869 pRaidPhysDiskPage1_t buffer = NULL;
5874 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5875 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5878 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5879 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5881 cfg.cfghdr.hdr = &hdr;
5883 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5885 if (mpt_config(ioc, &cfg) != 0) {
5890 if (!hdr.PageLength) {
5895 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5903 cfg.physAddr = dma_handle;
5904 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5905 cfg.pageAddr = phys_disk_num;
5907 if (mpt_config(ioc, &cfg) != 0) {
5912 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5913 phys_disk->PhysDiskNum = phys_disk_num;
5914 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5915 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5916 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5917 phys_disk->Path[i].OwnerIdentifier =
5918 buffer->Path[i].OwnerIdentifier;
5919 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5920 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5921 sas_address = le64_to_cpu(sas_address);
5922 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5923 memcpy(&sas_address,
5924 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5925 sas_address = le64_to_cpu(sas_address);
5926 memcpy(&phys_disk->Path[i].OwnerWWID,
5927 &sas_address, sizeof(__le64));
5933 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5938 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5942 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5943 * @ioc: Pointer to a Adapter Strucutre
5947 * -EFAULT if read of config page header fails or data pointer not NULL
5948 * -ENOMEM if pci_alloc failed
5951 mpt_findImVolumes(MPT_ADAPTER *ioc)
5955 dma_addr_t ioc2_dma;
5957 ConfigPageHeader_t header;
5962 if (!ioc->ir_firmware)
5965 /* Free the old page
5967 kfree(ioc->raid_data.pIocPg2);
5968 ioc->raid_data.pIocPg2 = NULL;
5969 mpt_inactive_raid_list_free(ioc);
5971 /* Read IOCP2 header then the page.
5973 header.PageVersion = 0;
5974 header.PageLength = 0;
5975 header.PageNumber = 2;
5976 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5977 cfg.cfghdr.hdr = &header;
5980 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5983 if (mpt_config(ioc, &cfg) != 0)
5986 if (header.PageLength == 0)
5989 iocpage2sz = header.PageLength * 4;
5990 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5994 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5995 cfg.physAddr = ioc2_dma;
5996 if (mpt_config(ioc, &cfg) != 0)
5999 mem = kmalloc(iocpage2sz, GFP_KERNEL);
6005 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
6006 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
6008 mpt_read_ioc_pg_3(ioc);
6010 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
6011 mpt_inactive_raid_volumes(ioc,
6012 pIoc2->RaidVolume[i].VolumeBus,
6013 pIoc2->RaidVolume[i].VolumeID);
6016 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
6022 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
6027 ConfigPageHeader_t header;
6028 dma_addr_t ioc3_dma;
6031 /* Free the old page
6033 kfree(ioc->raid_data.pIocPg3);
6034 ioc->raid_data.pIocPg3 = NULL;
6036 /* There is at least one physical disk.
6037 * Read and save IOC Page 3
6039 header.PageVersion = 0;
6040 header.PageLength = 0;
6041 header.PageNumber = 3;
6042 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6043 cfg.cfghdr.hdr = &header;
6046 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6049 if (mpt_config(ioc, &cfg) != 0)
6052 if (header.PageLength == 0)
6055 /* Read Header good, alloc memory
6057 iocpage3sz = header.PageLength * 4;
6058 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6062 /* Read the Page and save the data
6063 * into malloc'd memory.
6065 cfg.physAddr = ioc3_dma;
6066 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6067 if (mpt_config(ioc, &cfg) == 0) {
6068 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6070 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6071 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6075 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6081 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6085 ConfigPageHeader_t header;
6086 dma_addr_t ioc4_dma;
6089 /* Read and save IOC Page 4
6091 header.PageVersion = 0;
6092 header.PageLength = 0;
6093 header.PageNumber = 4;
6094 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6095 cfg.cfghdr.hdr = &header;
6098 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6101 if (mpt_config(ioc, &cfg) != 0)
6104 if (header.PageLength == 0)
6107 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6108 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6109 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6112 ioc->alloc_total += iocpage4sz;
6114 ioc4_dma = ioc->spi_data.IocPg4_dma;
6115 iocpage4sz = ioc->spi_data.IocPg4Sz;
6118 /* Read the Page into dma memory.
6120 cfg.physAddr = ioc4_dma;
6121 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6122 if (mpt_config(ioc, &cfg) == 0) {
6123 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6124 ioc->spi_data.IocPg4_dma = ioc4_dma;
6125 ioc->spi_data.IocPg4Sz = iocpage4sz;
6127 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6128 ioc->spi_data.pIocPg4 = NULL;
6129 ioc->alloc_total -= iocpage4sz;
6134 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6138 ConfigPageHeader_t header;
6139 dma_addr_t ioc1_dma;
6143 /* Check the Coalescing Timeout in IOC Page 1
6145 header.PageVersion = 0;
6146 header.PageLength = 0;
6147 header.PageNumber = 1;
6148 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6149 cfg.cfghdr.hdr = &header;
6152 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6155 if (mpt_config(ioc, &cfg) != 0)
6158 if (header.PageLength == 0)
6161 /* Read Header good, alloc memory
6163 iocpage1sz = header.PageLength * 4;
6164 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6168 /* Read the Page and check coalescing timeout
6170 cfg.physAddr = ioc1_dma;
6171 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6172 if (mpt_config(ioc, &cfg) == 0) {
6174 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6175 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6176 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6178 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6181 if (tmp > MPT_COALESCING_TIMEOUT) {
6182 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6184 /* Write NVRAM and current
6187 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6188 if (mpt_config(ioc, &cfg) == 0) {
6189 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6190 ioc->name, MPT_COALESCING_TIMEOUT));
6192 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6193 if (mpt_config(ioc, &cfg) == 0) {
6194 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6195 "Reset NVRAM Coalescing Timeout to = %d\n",
6196 ioc->name, MPT_COALESCING_TIMEOUT));
6198 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6199 "Reset NVRAM Coalescing Timeout Failed\n",
6204 dprintk(ioc, printk(MYIOC_s_WARN_FMT
6205 "Reset of Current Coalescing Timeout Failed!\n",
6211 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6215 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6221 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6224 ConfigPageHeader_t hdr;
6226 ManufacturingPage0_t *pbuf = NULL;
6228 memset(&cfg, 0 , sizeof(CONFIGPARMS));
6229 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6231 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6232 cfg.cfghdr.hdr = &hdr;
6234 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6237 if (mpt_config(ioc, &cfg) != 0)
6240 if (!cfg.cfghdr.hdr->PageLength)
6243 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6244 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6248 cfg.physAddr = buf_dma;
6250 if (mpt_config(ioc, &cfg) != 0)
6253 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6254 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6255 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6260 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6265 * SendEventNotification - Send EventNotification (on or off) request to adapter
6266 * @ioc: Pointer to MPT_ADAPTER structure
6267 * @EvSwitch: Event switch flags
6268 * @sleepFlag: Specifies whether the process can sleep
6271 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6273 EventNotification_t evn;
6274 MPIDefaultReply_t reply_buf;
6276 memset(&evn, 0, sizeof(EventNotification_t));
6277 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6279 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6280 evn.Switch = EvSwitch;
6281 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6283 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6284 "Sending EventNotification (%d) request %p\n",
6285 ioc->name, EvSwitch, &evn));
6287 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6288 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6294 * SendEventAck - Send EventAck request to MPT adapter.
6295 * @ioc: Pointer to MPT_ADAPTER structure
6296 * @evnp: Pointer to original EventNotification request
6299 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6303 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6304 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6305 ioc->name, __func__));
6309 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6311 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6312 pAck->ChainOffset = 0;
6313 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6315 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6316 pAck->Event = evnp->Event;
6317 pAck->EventContext = evnp->EventContext;
6319 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6324 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6326 * mpt_config - Generic function to issue config message
6327 * @ioc: Pointer to an adapter structure
6328 * @pCfg: Pointer to a configuration structure. Struct contains
6329 * action, page address, direction, physical address
6330 * and pointer to a configuration page header
6331 * Page header is updated.
6333 * Returns 0 for success
6334 * -EPERM if not allowed due to ISR context
6335 * -EAGAIN if no msg frames currently available
6336 * -EFAULT for non-successful reply or no reply (timeout)
6339 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6342 ConfigReply_t *pReply;
6343 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6349 u8 page_type = 0, extend_page;
6350 unsigned long timeleft;
6351 unsigned long flags;
6353 u8 issue_hard_reset = 0;
6356 /* Prevent calling wait_event() (below), if caller happens
6357 * to be in ISR context, because that is fatal!
6359 in_isr = in_interrupt();
6361 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6366 /* don't send a config page during diag reset */
6367 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6368 if (ioc->ioc_reset_in_progress) {
6369 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6370 "%s: busy with host reset\n", ioc->name, __func__));
6371 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6374 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6376 /* don't send if no chance of success */
6378 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6379 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6380 "%s: ioc not operational, %d, %xh\n",
6381 ioc->name, __func__, ioc->active,
6382 mpt_GetIocState(ioc, 0)));
6387 mutex_lock(&ioc->mptbase_cmds.mutex);
6388 /* init the internal cmd struct */
6389 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6390 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6392 /* Get and Populate a free Frame
6394 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6395 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6396 "mpt_config: no msg frames!\n", ioc->name));
6401 pReq = (Config_t *)mf;
6402 pReq->Action = pCfg->action;
6404 pReq->ChainOffset = 0;
6405 pReq->Function = MPI_FUNCTION_CONFIG;
6407 /* Assume page type is not extended and clear "reserved" fields. */
6408 pReq->ExtPageLength = 0;
6409 pReq->ExtPageType = 0;
6412 for (ii=0; ii < 8; ii++)
6413 pReq->Reserved2[ii] = 0;
6415 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6416 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6417 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6418 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6420 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6421 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6422 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6423 pReq->ExtPageType = pExtHdr->ExtPageType;
6424 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6426 /* Page Length must be treated as a reserved field for the
6429 pReq->Header.PageLength = 0;
6432 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6434 /* Add a SGE to the config request.
6437 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6439 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6441 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6442 MPI_CONFIG_PAGETYPE_EXTENDED) {
6443 flagsLength |= pExtHdr->ExtPageLength * 4;
6444 page_type = pReq->ExtPageType;
6447 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6448 page_type = pReq->Header.PageType;
6452 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6453 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6454 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6456 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6457 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6458 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6459 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6461 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6463 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6464 "Failed Sending Config request type 0x%x, page 0x%x,"
6465 " action %d, status %xh, time left %ld\n\n",
6466 ioc->name, page_type, pReq->Header.PageNumber,
6467 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6468 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6471 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6472 if (ioc->ioc_reset_in_progress) {
6473 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
6475 printk(MYIOC_s_INFO_FMT "%s: host reset in"
6476 " progress mpt_config timed out.!!\n",
6477 __func__, ioc->name);
6478 mutex_unlock(&ioc->mptbase_cmds.mutex);
6481 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6482 issue_hard_reset = 1;
6487 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6491 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6492 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6493 if (ret == MPI_IOCSTATUS_SUCCESS) {
6495 pCfg->cfghdr.ehdr->ExtPageLength =
6496 le16_to_cpu(pReply->ExtPageLength);
6497 pCfg->cfghdr.ehdr->ExtPageType =
6498 pReply->ExtPageType;
6500 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6501 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6502 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6503 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6508 printk(MYIOC_s_INFO_FMT "Retry completed "
6509 "ret=0x%x timeleft=%ld\n",
6510 ioc->name, ret, timeleft);
6512 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6513 ret, le32_to_cpu(pReply->IOCLogInfo)));
6517 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6518 mutex_unlock(&ioc->mptbase_cmds.mutex);
6519 if (issue_hard_reset) {
6520 issue_hard_reset = 0;
6521 printk(MYIOC_s_WARN_FMT
6522 "Issuing Reset from %s!!, doorbell=0x%08x\n",
6523 ioc->name, __func__, mpt_GetIocState(ioc, 0));
6524 if (retry_count == 0) {
6525 if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6528 mpt_HardResetHandler(ioc, CAN_SLEEP);
6530 mpt_free_msg_frame(ioc, mf);
6531 /* attempt one retry for a timed out command */
6532 if (retry_count < 2) {
6533 printk(MYIOC_s_INFO_FMT
6534 "Attempting Retry Config request"
6535 " type 0x%x, page 0x%x,"
6536 " action %d\n", ioc->name, page_type,
6537 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6546 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6548 * mpt_ioc_reset - Base cleanup for hard reset
6549 * @ioc: Pointer to the adapter structure
6550 * @reset_phase: Indicates pre- or post-reset functionality
6552 * Remark: Frees resources with internally generated commands.
6555 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6557 switch (reset_phase) {
6558 case MPT_IOC_SETUP_RESET:
6559 ioc->taskmgmt_quiesce_io = 1;
6560 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6561 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6563 case MPT_IOC_PRE_RESET:
6564 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6565 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6567 case MPT_IOC_POST_RESET:
6568 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6569 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6570 /* wake up mptbase_cmds */
6571 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6572 ioc->mptbase_cmds.status |=
6573 MPT_MGMT_STATUS_DID_IOCRESET;
6574 complete(&ioc->mptbase_cmds.done);
6576 /* wake up taskmgmt_cmds */
6577 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6578 ioc->taskmgmt_cmds.status |=
6579 MPT_MGMT_STATUS_DID_IOCRESET;
6580 complete(&ioc->taskmgmt_cmds.done);
6587 return 1; /* currently means nothing really */
6591 #ifdef CONFIG_PROC_FS /* { */
6592 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6594 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6598 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6600 * Returns 0 for success, non-zero for failure.
6603 procmpt_create(void)
6605 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6606 if (mpt_proc_root_dir == NULL)
6609 proc_create("summary", S_IRUGO, mpt_proc_root_dir, &mpt_summary_proc_fops);
6610 proc_create("version", S_IRUGO, mpt_proc_root_dir, &mpt_version_proc_fops);
6614 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6616 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6618 * Returns 0 for success, non-zero for failure.
6621 procmpt_destroy(void)
6623 remove_proc_entry("version", mpt_proc_root_dir);
6624 remove_proc_entry("summary", mpt_proc_root_dir);
6625 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6628 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6630 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6632 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6634 static int mpt_summary_proc_show(struct seq_file *m, void *v)
6636 MPT_ADAPTER *ioc = m->private;
6639 seq_mpt_print_ioc_summary(ioc, m, 1);
6641 list_for_each_entry(ioc, &ioc_list, list) {
6642 seq_mpt_print_ioc_summary(ioc, m, 1);
6649 static int mpt_summary_proc_open(struct inode *inode, struct file *file)
6651 return single_open(file, mpt_summary_proc_show, PDE_DATA(inode));
6654 static const struct file_operations mpt_summary_proc_fops = {
6655 .owner = THIS_MODULE,
6656 .open = mpt_summary_proc_open,
6658 .llseek = seq_lseek,
6659 .release = single_release,
6662 static int mpt_version_proc_show(struct seq_file *m, void *v)
6665 int scsi, fc, sas, lan, ctl, targ, dmp;
6668 seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6669 seq_printf(m, " Fusion MPT base driver\n");
6671 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6672 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6674 if (MptCallbacks[cb_idx]) {
6675 switch (MptDriverClass[cb_idx]) {
6677 if (!scsi++) drvname = "SPI host";
6680 if (!fc++) drvname = "FC host";
6683 if (!sas++) drvname = "SAS host";
6686 if (!lan++) drvname = "LAN";
6689 if (!targ++) drvname = "SCSI target";
6692 if (!ctl++) drvname = "ioctl";
6697 seq_printf(m, " Fusion MPT %s driver\n", drvname);
6704 static int mpt_version_proc_open(struct inode *inode, struct file *file)
6706 return single_open(file, mpt_version_proc_show, NULL);
6709 static const struct file_operations mpt_version_proc_fops = {
6710 .owner = THIS_MODULE,
6711 .open = mpt_version_proc_open,
6713 .llseek = seq_lseek,
6714 .release = single_release,
6717 static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
6719 MPT_ADAPTER *ioc = m->private;
6724 mpt_get_fw_exp_ver(expVer, ioc);
6726 seq_printf(m, "%s:", ioc->name);
6727 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6728 seq_printf(m, " (f/w download boot flag set)");
6729 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6730 // seq_printf(m, " CONFIG_CHECKSUM_FAIL!");
6732 seq_printf(m, "\n ProductID = 0x%04x (%s)\n",
6733 ioc->facts.ProductID,
6735 seq_printf(m, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6736 if (ioc->facts.FWImageSize)
6737 seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
6738 seq_printf(m, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6739 seq_printf(m, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6740 seq_printf(m, " EventState = 0x%02x\n", ioc->facts.EventState);
6742 seq_printf(m, " CurrentHostMfaHighAddr = 0x%08x\n",
6743 ioc->facts.CurrentHostMfaHighAddr);
6744 seq_printf(m, " CurrentSenseBufferHighAddr = 0x%08x\n",
6745 ioc->facts.CurrentSenseBufferHighAddr);
6747 seq_printf(m, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6748 seq_printf(m, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6750 seq_printf(m, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6751 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6753 * Rounding UP to nearest 4-kB boundary here...
6755 sz = (ioc->req_sz * ioc->req_depth) + 128;
6756 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6757 seq_printf(m, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6758 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6759 seq_printf(m, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6760 4*ioc->facts.RequestFrameSize,
6761 ioc->facts.GlobalCredits);
6763 seq_printf(m, " Frames @ 0x%p (Dma @ 0x%p)\n",
6764 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6765 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6766 seq_printf(m, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6767 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6768 seq_printf(m, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6769 ioc->facts.CurReplyFrameSize,
6770 ioc->facts.ReplyQueueDepth);
6772 seq_printf(m, " MaxDevices = %d\n",
6773 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6774 seq_printf(m, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6777 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6778 seq_printf(m, " PortNumber = %d (of %d)\n",
6780 ioc->facts.NumberOfPorts);
6781 if (ioc->bus_type == FC) {
6782 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6783 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6784 seq_printf(m, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6785 a[5], a[4], a[3], a[2], a[1], a[0]);
6787 seq_printf(m, " WWN = %08X%08X:%08X%08X\n",
6788 ioc->fc_port_page0[p].WWNN.High,
6789 ioc->fc_port_page0[p].WWNN.Low,
6790 ioc->fc_port_page0[p].WWPN.High,
6791 ioc->fc_port_page0[p].WWPN.Low);
6798 static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file)
6800 return single_open(file, mpt_iocinfo_proc_show, PDE_DATA(inode));
6803 static const struct file_operations mpt_iocinfo_proc_fops = {
6804 .owner = THIS_MODULE,
6805 .open = mpt_iocinfo_proc_open,
6807 .llseek = seq_lseek,
6808 .release = single_release,
6810 #endif /* CONFIG_PROC_FS } */
6812 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6814 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6817 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6818 sprintf(buf, " (Exp %02d%02d)",
6819 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6820 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6823 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6824 strcat(buf, " [MDBG]");
6828 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6830 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6831 * @ioc: Pointer to MPT_ADAPTER structure
6832 * @buffer: Pointer to buffer where IOC summary info should be written
6833 * @size: Pointer to number of bytes we wrote (set by this routine)
6834 * @len: Offset at which to start writing in buffer
6835 * @showlan: Display LAN stuff?
6837 * This routine writes (english readable) ASCII text, which represents
6838 * a summary of IOC information, to a buffer.
6841 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6846 mpt_get_fw_exp_ver(expVer, ioc);
6849 * Shorter summary of attached ioc's...
6851 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6854 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6855 ioc->facts.FWVersion.Word,
6857 ioc->facts.NumberOfPorts,
6860 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6861 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6862 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6863 a[5], a[4], a[3], a[2], a[1], a[0]);
6866 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6869 y += sprintf(buffer+len+y, " (disabled)");
6871 y += sprintf(buffer+len+y, "\n");
6876 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
6880 mpt_get_fw_exp_ver(expVer, ioc);
6883 * Shorter summary of attached ioc's...
6885 seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6888 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6889 ioc->facts.FWVersion.Word,
6891 ioc->facts.NumberOfPorts,
6894 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6895 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6896 seq_printf(m, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6897 a[5], a[4], a[3], a[2], a[1], a[0]);
6900 seq_printf(m, ", IRQ=%d", ioc->pci_irq);
6903 seq_printf(m, " (disabled)");
6909 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6910 * @ioc: Pointer to MPT_ADAPTER structure
6912 * Returns 0 for SUCCESS or -1 if FAILED.
6914 * If -1 is return, then it was not possible to set the flags
6917 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6919 unsigned long flags;
6922 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6923 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6924 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6929 ioc->taskmgmt_in_progress = 1;
6930 ioc->taskmgmt_quiesce_io = 1;
6932 ioc->alt_ioc->taskmgmt_in_progress = 1;
6933 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6936 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6939 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6942 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6943 * @ioc: Pointer to MPT_ADAPTER structure
6947 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6949 unsigned long flags;
6951 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6952 ioc->taskmgmt_in_progress = 0;
6953 ioc->taskmgmt_quiesce_io = 0;
6955 ioc->alt_ioc->taskmgmt_in_progress = 0;
6956 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6958 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6960 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6964 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6966 * @ioc: Pointer to MPT_ADAPTER structure
6970 mpt_halt_firmware(MPT_ADAPTER *ioc)
6974 ioc_raw_state = mpt_GetIocState(ioc, 0);
6976 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6977 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6978 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6979 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6980 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6982 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6983 panic("%s: Firmware is halted due to command timeout\n",
6987 EXPORT_SYMBOL(mpt_halt_firmware);
6990 * mpt_SoftResetHandler - Issues a less expensive reset
6991 * @ioc: Pointer to MPT_ADAPTER structure
6992 * @sleepFlag: Indicates if sleep or schedule must be called.
6994 * Returns 0 for SUCCESS or -1 if FAILED.
6996 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6997 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6998 * All posted buffers are freed, and event notification is turned off.
6999 * IOC doesn't reply to any outstanding request. This will transfer IOC
7003 mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7008 unsigned long flags;
7010 unsigned long time_count;
7012 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
7015 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7017 if (mpt_fwfault_debug)
7018 mpt_halt_firmware(ioc);
7020 if (ioc_state == MPI_IOC_STATE_FAULT ||
7021 ioc_state == MPI_IOC_STATE_RESET) {
7022 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7023 "skipping, either in FAULT or RESET state!\n", ioc->name));
7027 if (ioc->bus_type == FC) {
7028 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7029 "skipping, because the bus type is FC!\n", ioc->name));
7033 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7034 if (ioc->ioc_reset_in_progress) {
7035 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7038 ioc->ioc_reset_in_progress = 1;
7039 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7043 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7044 if (MptResetHandlers[cb_idx])
7045 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7048 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7049 if (ioc->taskmgmt_in_progress) {
7050 ioc->ioc_reset_in_progress = 0;
7051 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7054 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7055 /* Disable reply interrupts (also blocks FreeQ) */
7056 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
7058 time_count = jiffies;
7060 rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
7062 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7063 if (MptResetHandlers[cb_idx])
7064 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
7070 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7071 if (ioc_state != MPI_IOC_STATE_READY)
7074 for (ii = 0; ii < 5; ii++) {
7075 /* Get IOC facts! Allow 5 retries */
7076 rc = GetIocFacts(ioc, sleepFlag,
7077 MPT_HOSTEVENT_IOC_RECOVER);
7080 if (sleepFlag == CAN_SLEEP)
7088 rc = PrimeIocFifos(ioc);
7092 rc = SendIocInit(ioc, sleepFlag);
7096 rc = SendEventNotification(ioc, 1, sleepFlag);
7100 if (ioc->hard_resets < -1)
7104 * At this point, we know soft reset succeeded.
7108 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7111 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7112 ioc->ioc_reset_in_progress = 0;
7113 ioc->taskmgmt_quiesce_io = 0;
7114 ioc->taskmgmt_in_progress = 0;
7115 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7117 if (ioc->active) { /* otherwise, hard reset coming */
7118 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7119 if (MptResetHandlers[cb_idx])
7120 mpt_signal_reset(cb_idx, ioc,
7121 MPT_IOC_POST_RESET);
7125 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7126 "SoftResetHandler: completed (%d seconds): %s\n",
7127 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7128 ((rc == 0) ? "SUCCESS" : "FAILED")));
7134 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7135 * @ioc: Pointer to MPT_ADAPTER structure
7136 * @sleepFlag: Indicates if sleep or schedule must be called.
7138 * Returns 0 for SUCCESS or -1 if FAILED.
7139 * Try for softreset first, only if it fails go for expensive
7143 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7146 ret = mpt_SoftResetHandler(ioc, sleepFlag);
7149 ret = mpt_HardResetHandler(ioc, sleepFlag);
7152 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7154 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7160 * mpt_HardResetHandler - Generic reset handler
7161 * @ioc: Pointer to MPT_ADAPTER structure
7162 * @sleepFlag: Indicates if sleep or schedule must be called.
7164 * Issues SCSI Task Management call based on input arg values.
7165 * If TaskMgmt fails, returns associated SCSI request.
7167 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7168 * or a non-interrupt thread. In the former, must not call schedule().
7170 * Note: A return of -1 is a FATAL error case, as it means a
7171 * FW reload/initialization failed.
7173 * Returns 0 for SUCCESS or -1 if FAILED.
7176 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7180 unsigned long flags;
7181 unsigned long time_count;
7183 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7185 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7186 printk("MF count 0x%x !\n", ioc->mfcnt);
7188 if (mpt_fwfault_debug)
7189 mpt_halt_firmware(ioc);
7191 /* Reset the adapter. Prevent more than 1 call to
7192 * mpt_do_ioc_recovery at any instant in time.
7194 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7195 if (ioc->ioc_reset_in_progress) {
7196 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7197 ioc->wait_on_reset_completion = 1;
7200 } while (ioc->ioc_reset_in_progress == 1);
7201 ioc->wait_on_reset_completion = 0;
7202 return ioc->reset_status;
7204 if (ioc->wait_on_reset_completion) {
7205 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7207 time_count = jiffies;
7210 ioc->ioc_reset_in_progress = 1;
7212 ioc->alt_ioc->ioc_reset_in_progress = 1;
7213 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7216 /* The SCSI driver needs to adjust timeouts on all current
7217 * commands prior to the diagnostic reset being issued.
7218 * Prevents timeouts occurring during a diagnostic reset...very bad.
7219 * For all other protocol drivers, this is a no-op.
7221 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7222 if (MptResetHandlers[cb_idx]) {
7223 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7225 mpt_signal_reset(cb_idx, ioc->alt_ioc,
7226 MPT_IOC_SETUP_RESET);
7230 time_count = jiffies;
7231 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7233 printk(KERN_WARNING MYNAM
7234 ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7235 rc, ioc->name, mpt_GetIocState(ioc, 0));
7237 if (ioc->hard_resets < -1)
7241 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7242 ioc->ioc_reset_in_progress = 0;
7243 ioc->taskmgmt_quiesce_io = 0;
7244 ioc->taskmgmt_in_progress = 0;
7245 ioc->reset_status = rc;
7247 ioc->alt_ioc->ioc_reset_in_progress = 0;
7248 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7249 ioc->alt_ioc->taskmgmt_in_progress = 0;
7251 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7253 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7254 if (MptResetHandlers[cb_idx]) {
7255 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7257 mpt_signal_reset(cb_idx,
7258 ioc->alt_ioc, MPT_IOC_POST_RESET);
7263 printk(MYIOC_s_DEBUG_FMT
7264 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7265 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7266 "SUCCESS" : "FAILED")));
7271 #ifdef CONFIG_FUSION_LOGGING
7273 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7279 char *evStr = ioc->evStr;
7281 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7282 evData0 = le32_to_cpu(pEventReply->Data[0]);
7285 case MPI_EVENT_NONE:
7288 case MPI_EVENT_LOG_DATA:
7291 case MPI_EVENT_STATE_CHANGE:
7292 ds = "State Change";
7294 case MPI_EVENT_UNIT_ATTENTION:
7295 ds = "Unit Attention";
7297 case MPI_EVENT_IOC_BUS_RESET:
7298 ds = "IOC Bus Reset";
7300 case MPI_EVENT_EXT_BUS_RESET:
7301 ds = "External Bus Reset";
7303 case MPI_EVENT_RESCAN:
7304 ds = "Bus Rescan Event";
7306 case MPI_EVENT_LINK_STATUS_CHANGE:
7307 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7308 ds = "Link Status(FAILURE) Change";
7310 ds = "Link Status(ACTIVE) Change";
7312 case MPI_EVENT_LOOP_STATE_CHANGE:
7313 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7314 ds = "Loop State(LIP) Change";
7315 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7316 ds = "Loop State(LPE) Change";
7318 ds = "Loop State(LPB) Change";
7320 case MPI_EVENT_LOGOUT:
7323 case MPI_EVENT_EVENT_CHANGE:
7329 case MPI_EVENT_INTEGRATED_RAID:
7331 u8 ReasonCode = (u8)(evData0 >> 16);
7332 switch (ReasonCode) {
7333 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7334 ds = "Integrated Raid: Volume Created";
7336 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7337 ds = "Integrated Raid: Volume Deleted";
7339 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7340 ds = "Integrated Raid: Volume Settings Changed";
7342 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7343 ds = "Integrated Raid: Volume Status Changed";
7345 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7346 ds = "Integrated Raid: Volume Physdisk Changed";
7348 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7349 ds = "Integrated Raid: Physdisk Created";
7351 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7352 ds = "Integrated Raid: Physdisk Deleted";
7354 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7355 ds = "Integrated Raid: Physdisk Settings Changed";
7357 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7358 ds = "Integrated Raid: Physdisk Status Changed";
7360 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7361 ds = "Integrated Raid: Domain Validation Needed";
7363 case MPI_EVENT_RAID_RC_SMART_DATA :
7364 ds = "Integrated Raid; Smart Data";
7366 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7367 ds = "Integrated Raid: Replace Action Started";
7370 ds = "Integrated Raid";
7375 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7376 ds = "SCSI Device Status Change";
7378 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7380 u8 id = (u8)(evData0);
7381 u8 channel = (u8)(evData0 >> 8);
7382 u8 ReasonCode = (u8)(evData0 >> 16);
7383 switch (ReasonCode) {
7384 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7385 snprintf(evStr, EVENT_DESCR_STR_SZ,
7386 "SAS Device Status Change: Added: "
7387 "id=%d channel=%d", id, channel);
7389 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7390 snprintf(evStr, EVENT_DESCR_STR_SZ,
7391 "SAS Device Status Change: Deleted: "
7392 "id=%d channel=%d", id, channel);
7394 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7395 snprintf(evStr, EVENT_DESCR_STR_SZ,
7396 "SAS Device Status Change: SMART Data: "
7397 "id=%d channel=%d", id, channel);
7399 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7400 snprintf(evStr, EVENT_DESCR_STR_SZ,
7401 "SAS Device Status Change: No Persistancy: "
7402 "id=%d channel=%d", id, channel);
7404 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7405 snprintf(evStr, EVENT_DESCR_STR_SZ,
7406 "SAS Device Status Change: Unsupported Device "
7407 "Discovered : id=%d channel=%d", id, channel);
7409 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7410 snprintf(evStr, EVENT_DESCR_STR_SZ,
7411 "SAS Device Status Change: Internal Device "
7412 "Reset : id=%d channel=%d", id, channel);
7414 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7415 snprintf(evStr, EVENT_DESCR_STR_SZ,
7416 "SAS Device Status Change: Internal Task "
7417 "Abort : id=%d channel=%d", id, channel);
7419 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7420 snprintf(evStr, EVENT_DESCR_STR_SZ,
7421 "SAS Device Status Change: Internal Abort "
7422 "Task Set : id=%d channel=%d", id, channel);
7424 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7425 snprintf(evStr, EVENT_DESCR_STR_SZ,
7426 "SAS Device Status Change: Internal Clear "
7427 "Task Set : id=%d channel=%d", id, channel);
7429 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7430 snprintf(evStr, EVENT_DESCR_STR_SZ,
7431 "SAS Device Status Change: Internal Query "
7432 "Task : id=%d channel=%d", id, channel);
7435 snprintf(evStr, EVENT_DESCR_STR_SZ,
7436 "SAS Device Status Change: Unknown: "
7437 "id=%d channel=%d", id, channel);
7442 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7443 ds = "Bus Timer Expired";
7445 case MPI_EVENT_QUEUE_FULL:
7447 u16 curr_depth = (u16)(evData0 >> 16);
7448 u8 channel = (u8)(evData0 >> 8);
7449 u8 id = (u8)(evData0);
7451 snprintf(evStr, EVENT_DESCR_STR_SZ,
7452 "Queue Full: channel=%d id=%d depth=%d",
7453 channel, id, curr_depth);
7456 case MPI_EVENT_SAS_SES:
7457 ds = "SAS SES Event";
7459 case MPI_EVENT_PERSISTENT_TABLE_FULL:
7460 ds = "Persistent Table Full";
7462 case MPI_EVENT_SAS_PHY_LINK_STATUS:
7464 u8 LinkRates = (u8)(evData0 >> 8);
7465 u8 PhyNumber = (u8)(evData0);
7466 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7467 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7468 switch (LinkRates) {
7469 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7470 snprintf(evStr, EVENT_DESCR_STR_SZ,
7471 "SAS PHY Link Status: Phy=%d:"
7472 " Rate Unknown",PhyNumber);
7474 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7475 snprintf(evStr, EVENT_DESCR_STR_SZ,
7476 "SAS PHY Link Status: Phy=%d:"
7477 " Phy Disabled",PhyNumber);
7479 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7480 snprintf(evStr, EVENT_DESCR_STR_SZ,
7481 "SAS PHY Link Status: Phy=%d:"
7482 " Failed Speed Nego",PhyNumber);
7484 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7485 snprintf(evStr, EVENT_DESCR_STR_SZ,
7486 "SAS PHY Link Status: Phy=%d:"
7487 " Sata OOB Completed",PhyNumber);
7489 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7490 snprintf(evStr, EVENT_DESCR_STR_SZ,
7491 "SAS PHY Link Status: Phy=%d:"
7492 " Rate 1.5 Gbps",PhyNumber);
7494 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7495 snprintf(evStr, EVENT_DESCR_STR_SZ,
7496 "SAS PHY Link Status: Phy=%d:"
7497 " Rate 3.0 Gbps", PhyNumber);
7499 case MPI_EVENT_SAS_PLS_LR_RATE_6_0:
7500 snprintf(evStr, EVENT_DESCR_STR_SZ,
7501 "SAS PHY Link Status: Phy=%d:"
7502 " Rate 6.0 Gbps", PhyNumber);
7505 snprintf(evStr, EVENT_DESCR_STR_SZ,
7506 "SAS PHY Link Status: Phy=%d", PhyNumber);
7511 case MPI_EVENT_SAS_DISCOVERY_ERROR:
7512 ds = "SAS Discovery Error";
7514 case MPI_EVENT_IR_RESYNC_UPDATE:
7516 u8 resync_complete = (u8)(evData0 >> 16);
7517 snprintf(evStr, EVENT_DESCR_STR_SZ,
7518 "IR Resync Update: Complete = %d:",resync_complete);
7523 u8 id = (u8)(evData0);
7524 u8 channel = (u8)(evData0 >> 8);
7525 u8 phys_num = (u8)(evData0 >> 24);
7526 u8 ReasonCode = (u8)(evData0 >> 16);
7528 switch (ReasonCode) {
7529 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7530 snprintf(evStr, EVENT_DESCR_STR_SZ,
7531 "IR2: LD State Changed: "
7532 "id=%d channel=%d phys_num=%d",
7533 id, channel, phys_num);
7535 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7536 snprintf(evStr, EVENT_DESCR_STR_SZ,
7537 "IR2: PD State Changed "
7538 "id=%d channel=%d phys_num=%d",
7539 id, channel, phys_num);
7541 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7542 snprintf(evStr, EVENT_DESCR_STR_SZ,
7543 "IR2: Bad Block Table Full: "
7544 "id=%d channel=%d phys_num=%d",
7545 id, channel, phys_num);
7547 case MPI_EVENT_IR2_RC_PD_INSERTED:
7548 snprintf(evStr, EVENT_DESCR_STR_SZ,
7549 "IR2: PD Inserted: "
7550 "id=%d channel=%d phys_num=%d",
7551 id, channel, phys_num);
7553 case MPI_EVENT_IR2_RC_PD_REMOVED:
7554 snprintf(evStr, EVENT_DESCR_STR_SZ,
7556 "id=%d channel=%d phys_num=%d",
7557 id, channel, phys_num);
7559 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7560 snprintf(evStr, EVENT_DESCR_STR_SZ,
7561 "IR2: Foreign CFG Detected: "
7562 "id=%d channel=%d phys_num=%d",
7563 id, channel, phys_num);
7565 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7566 snprintf(evStr, EVENT_DESCR_STR_SZ,
7567 "IR2: Rebuild Medium Error: "
7568 "id=%d channel=%d phys_num=%d",
7569 id, channel, phys_num);
7571 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7572 snprintf(evStr, EVENT_DESCR_STR_SZ,
7573 "IR2: Dual Port Added: "
7574 "id=%d channel=%d phys_num=%d",
7575 id, channel, phys_num);
7577 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7578 snprintf(evStr, EVENT_DESCR_STR_SZ,
7579 "IR2: Dual Port Removed: "
7580 "id=%d channel=%d phys_num=%d",
7581 id, channel, phys_num);
7589 case MPI_EVENT_SAS_DISCOVERY:
7592 ds = "SAS Discovery: Start";
7594 ds = "SAS Discovery: Stop";
7597 case MPI_EVENT_LOG_ENTRY_ADDED:
7598 ds = "SAS Log Entry Added";
7601 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7603 u8 phy_num = (u8)(evData0);
7604 u8 port_num = (u8)(evData0 >> 8);
7605 u8 port_width = (u8)(evData0 >> 16);
7606 u8 primative = (u8)(evData0 >> 24);
7607 snprintf(evStr, EVENT_DESCR_STR_SZ,
7608 "SAS Broadcase Primative: phy=%d port=%d "
7609 "width=%d primative=0x%02x",
7610 phy_num, port_num, port_width, primative);
7614 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7616 u8 reason = (u8)(evData0);
7619 case MPI_EVENT_SAS_INIT_RC_ADDED:
7620 ds = "SAS Initiator Status Change: Added";
7622 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7623 ds = "SAS Initiator Status Change: Deleted";
7626 ds = "SAS Initiator Status Change";
7632 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7634 u8 max_init = (u8)(evData0);
7635 u8 current_init = (u8)(evData0 >> 8);
7637 snprintf(evStr, EVENT_DESCR_STR_SZ,
7638 "SAS Initiator Device Table Overflow: max initiators=%02d "
7639 "current initators=%02d",
7640 max_init, current_init);
7643 case MPI_EVENT_SAS_SMP_ERROR:
7645 u8 status = (u8)(evData0);
7646 u8 port_num = (u8)(evData0 >> 8);
7647 u8 result = (u8)(evData0 >> 16);
7649 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7650 snprintf(evStr, EVENT_DESCR_STR_SZ,
7651 "SAS SMP Error: port=%d result=0x%02x",
7653 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7654 snprintf(evStr, EVENT_DESCR_STR_SZ,
7655 "SAS SMP Error: port=%d : CRC Error",
7657 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7658 snprintf(evStr, EVENT_DESCR_STR_SZ,
7659 "SAS SMP Error: port=%d : Timeout",
7661 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7662 snprintf(evStr, EVENT_DESCR_STR_SZ,
7663 "SAS SMP Error: port=%d : No Destination",
7665 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7666 snprintf(evStr, EVENT_DESCR_STR_SZ,
7667 "SAS SMP Error: port=%d : Bad Destination",
7670 snprintf(evStr, EVENT_DESCR_STR_SZ,
7671 "SAS SMP Error: port=%d : status=0x%02x",
7676 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7678 u8 reason = (u8)(evData0);
7681 case MPI_EVENT_SAS_EXP_RC_ADDED:
7682 ds = "Expander Status Change: Added";
7684 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7685 ds = "Expander Status Change: Deleted";
7688 ds = "Expander Status Change";
7695 * MPT base "custom" events may be added here...
7702 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7705 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7706 "MPT event:(%02Xh) : %s\n",
7707 ioc->name, event, evStr));
7709 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7710 ": Event data:\n"));
7711 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7712 devtverboseprintk(ioc, printk(" %08x",
7713 le32_to_cpu(pEventReply->Data[ii])));
7714 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7717 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7719 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7720 * @ioc: Pointer to MPT_ADAPTER structure
7721 * @pEventReply: Pointer to EventNotification reply frame
7722 * @evHandlers: Pointer to integer, number of event handlers
7724 * Routes a received EventNotificationReply to all currently registered
7726 * Returns sum of event handlers return values.
7729 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7740 * Do platform normalization of values
7742 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7743 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7745 evData0 = le32_to_cpu(pEventReply->Data[0]);
7748 #ifdef CONFIG_FUSION_LOGGING
7750 mpt_display_event_info(ioc, pEventReply);
7754 * Do general / base driver event processing
7757 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7759 u8 evState = evData0 & 0xFF;
7761 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7763 /* Update EventState field in cached IocFacts */
7764 if (ioc->facts.Function) {
7765 ioc->facts.EventState = evState;
7769 case MPI_EVENT_INTEGRATED_RAID:
7770 mptbase_raid_process_event_data(ioc,
7771 (MpiEventDataRaid_t *)pEventReply->Data);
7778 * Should this event be logged? Events are written sequentially.
7779 * When buffer is full, start again at the top.
7781 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7784 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7786 ioc->events[idx].event = event;
7787 ioc->events[idx].eventContext = ioc->eventContext;
7789 for (ii = 0; ii < 2; ii++) {
7791 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7793 ioc->events[idx].data[ii] = 0;
7796 ioc->eventContext++;
7801 * Call each currently registered protocol event handler.
7803 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7804 if (MptEvHandlers[cb_idx]) {
7805 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7806 "Routing Event to event handler #%d\n",
7807 ioc->name, cb_idx));
7808 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7812 /* FIXME? Examine results here? */
7815 * If needed, send (a single) EventAck.
7817 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7818 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7819 "EventAck required\n",ioc->name));
7820 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7821 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7826 *evHandlers = handlers;
7830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7832 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7833 * @ioc: Pointer to MPT_ADAPTER structure
7834 * @log_info: U32 LogInfo reply word from the IOC
7836 * Refer to lsi/mpi_log_fc.h.
7839 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7841 char *desc = "unknown";
7843 switch (log_info & 0xFF000000) {
7844 case MPI_IOCLOGINFO_FC_INIT_BASE:
7845 desc = "FCP Initiator";
7847 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7848 desc = "FCP Target";
7850 case MPI_IOCLOGINFO_FC_LAN_BASE:
7853 case MPI_IOCLOGINFO_FC_MSG_BASE:
7854 desc = "MPI Message Layer";
7856 case MPI_IOCLOGINFO_FC_LINK_BASE:
7859 case MPI_IOCLOGINFO_FC_CTX_BASE:
7860 desc = "Context Manager";
7862 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7863 desc = "Invalid Field Offset";
7865 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7866 desc = "State Change Info";
7870 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7871 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7874 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7876 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7877 * @ioc: Pointer to MPT_ADAPTER structure
7878 * @log_info: U32 LogInfo word from the IOC
7880 * Refer to lsi/sp_log.h.
7883 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7885 u32 info = log_info & 0x00FF0000;
7886 char *desc = "unknown";
7890 desc = "bug! MID not found";
7894 desc = "Parity Error";
7898 desc = "ASYNC Outbound Overrun";
7902 desc = "SYNC Offset Error";
7910 desc = "Msg In Overflow";
7918 desc = "Outbound DMA Overrun";
7922 desc = "Task Management";
7926 desc = "Device Problem";
7930 desc = "Invalid Phase Change";
7934 desc = "Untagged Table Size";
7939 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7942 /* strings for sas loginfo */
7943 static char *originator_str[] = {
7948 static char *iop_code_str[] = {
7950 "Invalid SAS Address", /* 01h */
7952 "Invalid Page", /* 03h */
7953 "Diag Message Error", /* 04h */
7954 "Task Terminated", /* 05h */
7955 "Enclosure Management", /* 06h */
7956 "Target Mode" /* 07h */
7958 static char *pl_code_str[] = {
7960 "Open Failure", /* 01h */
7961 "Invalid Scatter Gather List", /* 02h */
7962 "Wrong Relative Offset or Frame Length", /* 03h */
7963 "Frame Transfer Error", /* 04h */
7964 "Transmit Frame Connected Low", /* 05h */
7965 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7966 "SATA Read Log Receive Data Error", /* 07h */
7967 "SATA NCQ Fail All Commands After Error", /* 08h */
7968 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7969 "Receive Frame Invalid Message", /* 0Ah */
7970 "Receive Context Message Valid Error", /* 0Bh */
7971 "Receive Frame Current Frame Error", /* 0Ch */
7972 "SATA Link Down", /* 0Dh */
7973 "Discovery SATA Init W IOS", /* 0Eh */
7974 "Config Invalid Page", /* 0Fh */
7975 "Discovery SATA Init Timeout", /* 10h */
7978 "IO Not Yet Executed", /* 13h */
7979 "IO Executed", /* 14h */
7980 "Persistent Reservation Out Not Affiliation "
7982 "Open Transmit DMA Abort", /* 16h */
7983 "IO Device Missing Delay Retry", /* 17h */
7984 "IO Cancelled Due to Receive Error", /* 18h */
7992 "Enclosure Management" /* 20h */
7994 static char *ir_code_str[] = {
7995 "Raid Action Error", /* 00h */
8005 static char *raid_sub_code_str[] = {
8007 "Volume Creation Failed: Data Passed too "
8009 "Volume Creation Failed: Duplicate Volumes "
8010 "Attempted", /* 02h */
8011 "Volume Creation Failed: Max Number "
8012 "Supported Volumes Exceeded", /* 03h */
8013 "Volume Creation Failed: DMA Error", /* 04h */
8014 "Volume Creation Failed: Invalid Volume Type", /* 05h */
8015 "Volume Creation Failed: Error Reading "
8016 "MFG Page 4", /* 06h */
8017 "Volume Creation Failed: Creating Internal "
8018 "Structures", /* 07h */
8027 "Activation failed: Already Active Volume", /* 10h */
8028 "Activation failed: Unsupported Volume Type", /* 11h */
8029 "Activation failed: Too Many Active Volumes", /* 12h */
8030 "Activation failed: Volume ID in Use", /* 13h */
8031 "Activation failed: Reported Failure", /* 14h */
8032 "Activation failed: Importing a Volume", /* 15h */
8043 "Phys Disk failed: Too Many Phys Disks", /* 20h */
8044 "Phys Disk failed: Data Passed too Large", /* 21h */
8045 "Phys Disk failed: DMA Error", /* 22h */
8046 "Phys Disk failed: Invalid <channel:id>", /* 23h */
8047 "Phys Disk failed: Creating Phys Disk Config "
8060 "Compatibility Error: IR Disabled", /* 30h */
8061 "Compatibility Error: Inquiry Command Failed", /* 31h */
8062 "Compatibility Error: Device not Direct Access "
8063 "Device ", /* 32h */
8064 "Compatibility Error: Removable Device Found", /* 33h */
8065 "Compatibility Error: Device SCSI Version not "
8066 "2 or Higher", /* 34h */
8067 "Compatibility Error: SATA Device, 48 BIT LBA "
8068 "not Supported", /* 35h */
8069 "Compatibility Error: Device doesn't have "
8070 "512 Byte Block Sizes", /* 36h */
8071 "Compatibility Error: Volume Type Check Failed", /* 37h */
8072 "Compatibility Error: Volume Type is "
8073 "Unsupported by FW", /* 38h */
8074 "Compatibility Error: Disk Drive too Small for "
8075 "use in Volume", /* 39h */
8076 "Compatibility Error: Phys Disk for Create "
8077 "Volume not Found", /* 3Ah */
8078 "Compatibility Error: Too Many or too Few "
8079 "Disks for Volume Type", /* 3Bh */
8080 "Compatibility Error: Disk stripe Sizes "
8081 "Must be 64KB", /* 3Ch */
8082 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8085 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8087 * mpt_sas_log_info - Log information returned from SAS IOC.
8088 * @ioc: Pointer to MPT_ADAPTER structure
8089 * @log_info: U32 LogInfo reply word from the IOC
8090 * @cb_idx: callback function's handle
8092 * Refer to lsi/mpi_log_sas.h.
8095 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
8097 union loginfo_type {
8106 union loginfo_type sas_loginfo;
8107 char *originator_desc = NULL;
8108 char *code_desc = NULL;
8109 char *sub_code_desc = NULL;
8111 sas_loginfo.loginfo = log_info;
8112 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8113 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8116 originator_desc = originator_str[sas_loginfo.dw.originator];
8118 switch (sas_loginfo.dw.originator) {
8121 if (sas_loginfo.dw.code <
8122 ARRAY_SIZE(iop_code_str))
8123 code_desc = iop_code_str[sas_loginfo.dw.code];
8126 if (sas_loginfo.dw.code <
8127 ARRAY_SIZE(pl_code_str))
8128 code_desc = pl_code_str[sas_loginfo.dw.code];
8131 if (sas_loginfo.dw.code >=
8132 ARRAY_SIZE(ir_code_str))
8134 code_desc = ir_code_str[sas_loginfo.dw.code];
8135 if (sas_loginfo.dw.subcode >=
8136 ARRAY_SIZE(raid_sub_code_str))
8138 if (sas_loginfo.dw.code == 0)
8140 raid_sub_code_str[sas_loginfo.dw.subcode];
8146 if (sub_code_desc != NULL)
8147 printk(MYIOC_s_INFO_FMT
8148 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8149 " SubCode={%s} cb_idx %s\n",
8150 ioc->name, log_info, originator_desc, code_desc,
8151 sub_code_desc, MptCallbacksName[cb_idx]);
8152 else if (code_desc != NULL)
8153 printk(MYIOC_s_INFO_FMT
8154 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8155 " SubCode(0x%04x) cb_idx %s\n",
8156 ioc->name, log_info, originator_desc, code_desc,
8157 sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]);
8159 printk(MYIOC_s_INFO_FMT
8160 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8161 " SubCode(0x%04x) cb_idx %s\n",
8162 ioc->name, log_info, originator_desc,
8163 sas_loginfo.dw.code, sas_loginfo.dw.subcode,
8164 MptCallbacksName[cb_idx]);
8167 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8169 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8170 * @ioc: Pointer to MPT_ADAPTER structure
8171 * @ioc_status: U32 IOCStatus word from IOC
8172 * @mf: Pointer to MPT request frame
8174 * Refer to lsi/mpi.h.
8177 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8179 Config_t *pReq = (Config_t *)mf;
8180 char extend_desc[EVENT_DESCR_STR_SZ];
8185 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8186 page_type = pReq->ExtPageType;
8188 page_type = pReq->Header.PageType;
8191 * ignore invalid page messages for GET_NEXT_HANDLE
8193 form = le32_to_cpu(pReq->PageAddress);
8194 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8195 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8196 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8197 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8198 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8199 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8202 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8203 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8204 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8208 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8209 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8210 page_type, pReq->Header.PageNumber, pReq->Action, form);
8212 switch (ioc_status) {
8214 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8215 desc = "Config Page Invalid Action";
8218 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8219 desc = "Config Page Invalid Type";
8222 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8223 desc = "Config Page Invalid Page";
8226 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8227 desc = "Config Page Invalid Data";
8230 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8231 desc = "Config Page No Defaults";
8234 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8235 desc = "Config Page Can't Commit";
8242 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8243 ioc->name, ioc_status, desc, extend_desc));
8247 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8248 * @ioc: Pointer to MPT_ADAPTER structure
8249 * @ioc_status: U32 IOCStatus word from IOC
8250 * @mf: Pointer to MPT request frame
8252 * Refer to lsi/mpi.h.
8255 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8257 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8262 /****************************************************************************/
8263 /* Common IOCStatus values for all replies */
8264 /****************************************************************************/
8266 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8267 desc = "Invalid Function";
8270 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8274 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8275 desc = "Invalid SGL";
8278 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8279 desc = "Internal Error";
8282 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8286 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8287 desc = "Insufficient Resources";
8290 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8291 desc = "Invalid Field";
8294 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8295 desc = "Invalid State";
8298 /****************************************************************************/
8299 /* Config IOCStatus values */
8300 /****************************************************************************/
8302 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8303 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8304 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8305 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8306 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8307 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8308 mpt_iocstatus_info_config(ioc, status, mf);
8311 /****************************************************************************/
8312 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8314 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8316 /****************************************************************************/
8318 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8319 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8320 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8321 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8322 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8323 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8324 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8325 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8326 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8327 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8328 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8329 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8330 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8333 /****************************************************************************/
8334 /* SCSI Target values */
8335 /****************************************************************************/
8337 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8338 desc = "Target: Priority IO";
8341 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8342 desc = "Target: Invalid Port";
8345 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8346 desc = "Target Invalid IO Index:";
8349 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8350 desc = "Target: Aborted";
8353 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8354 desc = "Target: No Conn Retryable";
8357 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8358 desc = "Target: No Connection";
8361 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8362 desc = "Target: Transfer Count Mismatch";
8365 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8366 desc = "Target: STS Data not Sent";
8369 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8370 desc = "Target: Data Offset Error";
8373 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8374 desc = "Target: Too Much Write Data";
8377 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8378 desc = "Target: IU Too Short";
8381 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8382 desc = "Target: ACK NAK Timeout";
8385 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8386 desc = "Target: Nak Received";
8389 /****************************************************************************/
8390 /* Fibre Channel Direct Access values */
8391 /****************************************************************************/
8393 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8394 desc = "FC: Aborted";
8397 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8398 desc = "FC: RX ID Invalid";
8401 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8402 desc = "FC: DID Invalid";
8405 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8406 desc = "FC: Node Logged Out";
8409 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8410 desc = "FC: Exchange Canceled";
8413 /****************************************************************************/
8415 /****************************************************************************/
8417 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8418 desc = "LAN: Device not Found";
8421 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8422 desc = "LAN: Device Failure";
8425 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8426 desc = "LAN: Transmit Error";
8429 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8430 desc = "LAN: Transmit Aborted";
8433 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8434 desc = "LAN: Receive Error";
8437 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8438 desc = "LAN: Receive Aborted";
8441 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8442 desc = "LAN: Partial Packet";
8445 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8446 desc = "LAN: Canceled";
8449 /****************************************************************************/
8450 /* Serial Attached SCSI values */
8451 /****************************************************************************/
8453 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8454 desc = "SAS: SMP Request Failed";
8457 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8458 desc = "SAS: SMP Data Overrun";
8469 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8470 ioc->name, status, desc));
8473 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8474 EXPORT_SYMBOL(mpt_attach);
8475 EXPORT_SYMBOL(mpt_detach);
8477 EXPORT_SYMBOL(mpt_resume);
8478 EXPORT_SYMBOL(mpt_suspend);
8480 EXPORT_SYMBOL(ioc_list);
8481 EXPORT_SYMBOL(mpt_register);
8482 EXPORT_SYMBOL(mpt_deregister);
8483 EXPORT_SYMBOL(mpt_event_register);
8484 EXPORT_SYMBOL(mpt_event_deregister);
8485 EXPORT_SYMBOL(mpt_reset_register);
8486 EXPORT_SYMBOL(mpt_reset_deregister);
8487 EXPORT_SYMBOL(mpt_device_driver_register);
8488 EXPORT_SYMBOL(mpt_device_driver_deregister);
8489 EXPORT_SYMBOL(mpt_get_msg_frame);
8490 EXPORT_SYMBOL(mpt_put_msg_frame);
8491 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8492 EXPORT_SYMBOL(mpt_free_msg_frame);
8493 EXPORT_SYMBOL(mpt_send_handshake_request);
8494 EXPORT_SYMBOL(mpt_verify_adapter);
8495 EXPORT_SYMBOL(mpt_GetIocState);
8496 EXPORT_SYMBOL(mpt_print_ioc_summary);
8497 EXPORT_SYMBOL(mpt_HardResetHandler);
8498 EXPORT_SYMBOL(mpt_config);
8499 EXPORT_SYMBOL(mpt_findImVolumes);
8500 EXPORT_SYMBOL(mpt_alloc_fw_memory);
8501 EXPORT_SYMBOL(mpt_free_fw_memory);
8502 EXPORT_SYMBOL(mptbase_sas_persist_operation);
8503 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8505 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8507 * fusion_init - Fusion MPT base driver initialization routine.
8509 * Returns 0 for success, non-zero for failure.
8516 show_mptmod_ver(my_NAME, my_VERSION);
8517 printk(KERN_INFO COPYRIGHT "\n");
8519 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8520 MptCallbacks[cb_idx] = NULL;
8521 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8522 MptEvHandlers[cb_idx] = NULL;
8523 MptResetHandlers[cb_idx] = NULL;
8526 /* Register ourselves (mptbase) in order to facilitate
8527 * EventNotification handling.
8529 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER,
8532 /* Register for hard reset handling callbacks.
8534 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8536 #ifdef CONFIG_PROC_FS
8537 (void) procmpt_create();
8542 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8544 * fusion_exit - Perform driver unload cleanup.
8546 * This routine frees all resources associated with each MPT adapter
8547 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8553 mpt_reset_deregister(mpt_base_index);
8555 #ifdef CONFIG_PROC_FS
8560 module_init(fusion_init);
8561 module_exit(fusion_exit);