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/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
61 #include <linux/sort.h>
68 #include "lsi/mpi_log_fc.h"
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME "Fusion MPT base driver"
72 #define my_VERSION MPT_LINUX_VERSION_COMMON
73 #define MYNAM "mptbase"
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
78 MODULE_VERSION(my_VERSION);
84 static int mpt_msi_enable_spi;
85 module_param(mpt_msi_enable_spi, int, 0);
86 MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \
87 controllers (default=0)");
89 static int mpt_msi_enable_fc;
90 module_param(mpt_msi_enable_fc, int, 0);
91 MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
92 controllers (default=0)");
94 static int mpt_msi_enable_sas;
95 module_param(mpt_msi_enable_sas, int, 0);
96 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
97 controllers (default=0)");
100 static int mpt_channel_mapping;
101 module_param(mpt_channel_mapping, int, 0);
102 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
105 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
106 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
107 &mpt_debug_level, 0600);
108 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
110 EXPORT_SYMBOL(mpt_debug_level);
112 int mpt_fwfault_debug;
113 EXPORT_SYMBOL(mpt_fwfault_debug);
114 module_param_call(mpt_fwfault_debug, param_set_int, param_get_int,
115 &mpt_fwfault_debug, 0600);
116 MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
117 " and halt Firmware on fault - (default=0)");
122 static int mfcounter = 0;
123 #define PRINT_MF_COUNT 20000
126 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
131 struct proc_dir_entry *mpt_proc_root_dir;
133 #define WHOINIT_UNKNOWN 0xAA
135 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
139 /* Adapter link list */
141 /* Callback lookup table */
142 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
143 /* Protocol driver class lookup table */
144 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
145 /* Event handler lookup table */
146 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147 /* Reset handler lookup table */
148 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
149 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
153 * Driver Callback Index's
155 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
156 static u8 last_drv_idx;
158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
162 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
163 MPT_FRAME_HDR *reply);
164 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
165 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
167 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
168 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
169 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
170 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
172 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
173 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
174 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
175 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
176 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
177 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
178 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
179 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
180 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
181 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
182 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
183 static int PrimeIocFifos(MPT_ADAPTER *ioc);
184 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
185 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
187 static int GetLanConfigPages(MPT_ADAPTER *ioc);
188 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
189 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
190 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
191 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
192 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
193 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
194 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
195 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
197 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
198 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
199 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
201 #ifdef CONFIG_PROC_FS
202 static int procmpt_summary_read(char *buf, char **start, off_t offset,
203 int request, int *eof, void *data);
204 static int procmpt_version_read(char *buf, char **start, off_t offset,
205 int request, int *eof, void *data);
206 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
207 int request, int *eof, void *data);
209 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
211 static int ProcessEventNotification(MPT_ADAPTER *ioc,
212 EventNotificationReply_t *evReply, int *evHandlers);
213 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
214 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
215 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
216 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
217 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
218 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
220 /* module entry point */
221 static int __init fusion_init (void);
222 static void __exit fusion_exit (void);
224 #define CHIPREG_READ32(addr) readl_relaxed(addr)
225 #define CHIPREG_READ32_dmasync(addr) readl(addr)
226 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
227 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
228 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
231 pci_disable_io_access(struct pci_dev *pdev)
235 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
237 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
241 pci_enable_io_access(struct pci_dev *pdev)
245 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
247 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
251 * mpt_set_debug_level - global setting of the mpt_debug_level
252 * found via /sys/module/mptbase/parameters/mpt_debug_level
259 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
261 int ret = param_set_int(val, kp);
267 list_for_each_entry(ioc, &ioc_list, list)
268 ioc->debug_level = mpt_debug_level;
273 * mpt_get_cb_idx - obtain cb_idx for registered driver
274 * @dclass: class driver enum
276 * Returns cb_idx, or zero means it wasn't found
279 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
283 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
284 if (MptDriverClass[cb_idx] == dclass)
290 * mpt_is_discovery_complete - determine if discovery has completed
291 * @ioc: per adatper instance
293 * Returns 1 when discovery completed, else zero.
296 mpt_is_discovery_complete(MPT_ADAPTER *ioc)
298 ConfigExtendedPageHeader_t hdr;
300 SasIOUnitPage0_t *buffer;
301 dma_addr_t dma_handle;
304 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
305 memset(&cfg, 0, sizeof(CONFIGPARMS));
306 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
307 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
308 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
309 cfg.cfghdr.ehdr = &hdr;
310 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
312 if ((mpt_config(ioc, &cfg)))
314 if (!hdr.ExtPageLength)
317 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
322 cfg.physAddr = dma_handle;
323 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
325 if ((mpt_config(ioc, &cfg)))
326 goto out_free_consistent;
328 if (!(buffer->PhyData[0].PortFlags &
329 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
333 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
340 * mpt_fault_reset_work - work performed on workq after ioc fault
341 * @work: input argument, used to derive ioc
345 mpt_fault_reset_work(struct work_struct *work)
348 container_of(work, MPT_ADAPTER, fault_reset_work.work);
353 if (ioc->ioc_reset_in_progress || !ioc->active)
356 ioc_raw_state = mpt_GetIocState(ioc, 0);
357 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
358 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
359 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
360 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
361 ioc->name, __func__);
362 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
363 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
364 __func__, (rc == 0) ? "success" : "failed");
365 ioc_raw_state = mpt_GetIocState(ioc, 0);
366 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
367 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
368 "reset (%04xh)\n", ioc->name, ioc_raw_state &
369 MPI_DOORBELL_DATA_MASK);
370 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
371 if ((mpt_is_discovery_complete(ioc))) {
372 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
373 "discovery_quiesce_io flag\n", ioc->name));
374 ioc->sas_discovery_quiesce_io = 0;
380 * Take turns polling alternate controller
385 /* rearm the timer */
386 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
387 if (ioc->reset_work_q)
388 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
389 msecs_to_jiffies(MPT_POLLING_INTERVAL));
390 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
395 * Process turbo (context) reply...
398 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
400 MPT_FRAME_HDR *mf = NULL;
401 MPT_FRAME_HDR *mr = NULL;
405 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
408 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
409 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
410 req_idx = pa & 0x0000FFFF;
411 cb_idx = (pa & 0x00FF0000) >> 16;
412 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
414 case MPI_CONTEXT_REPLY_TYPE_LAN:
415 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
417 * Blind set of mf to NULL here was fatal
418 * after lan_reply says "freeme"
419 * Fix sort of combined with an optimization here;
420 * added explicit check for case where lan_reply
421 * was just returning 1 and doing nothing else.
422 * For this case skip the callback, but set up
423 * proper mf value first here:-)
425 if ((pa & 0x58000000) == 0x58000000) {
426 req_idx = pa & 0x0000FFFF;
427 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
428 mpt_free_msg_frame(ioc, mf);
433 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
435 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
436 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
437 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
444 /* Check for (valid) IO callback! */
445 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
446 MptCallbacks[cb_idx] == NULL) {
447 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
448 __func__, ioc->name, cb_idx);
452 if (MptCallbacks[cb_idx](ioc, mf, mr))
453 mpt_free_msg_frame(ioc, mf);
459 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
470 /* non-TURBO reply! Hmmm, something may be up...
471 * Newest turbo reply mechanism; get address
472 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
475 /* Map DMA address of reply header to cpu address.
476 * pa is 32 bits - but the dma address may be 32 or 64 bits
477 * get offset based only only the low addresses
480 reply_dma_low = (pa <<= 1);
481 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
482 (reply_dma_low - ioc->reply_frames_low_dma));
484 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
485 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
486 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
488 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
489 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
490 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
492 /* Check/log IOC log info
494 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
495 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
496 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
497 if (ioc->bus_type == FC)
498 mpt_fc_log_info(ioc, log_info);
499 else if (ioc->bus_type == SPI)
500 mpt_spi_log_info(ioc, log_info);
501 else if (ioc->bus_type == SAS)
502 mpt_sas_log_info(ioc, log_info);
505 /* TODO - add shost_attrs, or command line option, and
506 * extend this to SAS/FC
508 if (ioc_stat & MPI_IOCSTATUS_MASK)
509 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
511 /* Check for (valid) IO callback! */
512 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
513 MptCallbacks[cb_idx] == NULL) {
514 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
515 __func__, ioc->name, cb_idx);
520 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
523 /* Flush (non-TURBO) reply with a WRITE! */
524 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
527 mpt_free_msg_frame(ioc, mf);
531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
533 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
534 * @irq: irq number (not used)
535 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
537 * This routine is registered via the request_irq() kernel API call,
538 * and handles all interrupts generated from a specific MPT adapter
539 * (also referred to as a IO Controller or IOC).
540 * This routine must clear the interrupt from the adapter and does
541 * so by reading the reply FIFO. Multiple replies may be processed
542 * per single call to this routine.
544 * This routine handles register-level access of the adapter but
545 * dispatches (calls) a protocol-specific callback routine to handle
546 * the protocol-specific details of the MPT request completion.
549 mpt_interrupt(int irq, void *bus_id)
551 MPT_ADAPTER *ioc = bus_id;
552 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
554 if (pa == 0xFFFFFFFF)
558 * Drain the reply FIFO!
561 if (pa & MPI_ADDRESS_REPLY_A_BIT)
564 mpt_turbo_reply(ioc, pa);
565 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
566 } while (pa != 0xFFFFFFFF);
571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
573 * mptbase_reply - MPT base driver's callback routine
574 * @ioc: Pointer to MPT_ADAPTER structure
575 * @req: Pointer to original MPT request frame
576 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
578 * MPT base driver's callback routine; all base driver
579 * "internal" request/reply processing is routed here.
580 * Currently used for EventNotification and EventAck handling.
582 * Returns 1 indicating original alloc'd request frame ptr
583 * should be freed, or 0 if it shouldn't.
586 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
588 EventNotificationReply_t *pEventReply;
593 switch (reply->u.hdr.Function) {
594 case MPI_FUNCTION_EVENT_NOTIFICATION:
595 pEventReply = (EventNotificationReply_t *)reply;
597 ProcessEventNotification(ioc, pEventReply, &evHandlers);
598 event = le32_to_cpu(pEventReply->Event) & 0xFF;
599 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
601 if (event != MPI_EVENT_EVENT_CHANGE)
603 case MPI_FUNCTION_CONFIG:
604 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
605 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
607 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
608 memcpy(ioc->mptbase_cmds.reply, reply,
609 min(MPT_DEFAULT_FRAME_SIZE,
610 4 * reply->u.reply.MsgLength));
612 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
613 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
614 complete(&ioc->mptbase_cmds.done);
617 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
620 case MPI_FUNCTION_EVENT_ACK:
621 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
622 "EventAck reply received\n", ioc->name));
625 printk(MYIOC_s_ERR_FMT
626 "Unexpected msg function (=%02Xh) reply received!\n",
627 ioc->name, reply->u.hdr.Function);
632 * Conditionally tell caller to free the original
633 * EventNotification/EventAck/unexpected request frame!
638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
640 * mpt_register - Register protocol-specific main callback handler.
641 * @cbfunc: callback function pointer
642 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
644 * This routine is called by a protocol-specific driver (SCSI host,
645 * LAN, SCSI target) to register its reply callback routine. Each
646 * protocol-specific driver must do this before it will be able to
647 * use any IOC resources, such as obtaining request frames.
649 * NOTES: The SCSI protocol driver currently calls this routine thrice
650 * in order to register separate callbacks; one for "normal" SCSI IO;
651 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
653 * Returns u8 valued "handle" in the range (and S.O.D. order)
654 * {N,...,7,6,5,...,1} if successful.
655 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
656 * considered an error by the caller.
659 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
662 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
665 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
666 * (slot/handle 0 is reserved!)
668 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
669 if (MptCallbacks[cb_idx] == NULL) {
670 MptCallbacks[cb_idx] = cbfunc;
671 MptDriverClass[cb_idx] = dclass;
672 MptEvHandlers[cb_idx] = NULL;
673 last_drv_idx = cb_idx;
681 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
683 * mpt_deregister - Deregister a protocol drivers resources.
684 * @cb_idx: previously registered callback handle
686 * Each protocol-specific driver should call this routine when its
687 * module is unloaded.
690 mpt_deregister(u8 cb_idx)
692 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
693 MptCallbacks[cb_idx] = NULL;
694 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
695 MptEvHandlers[cb_idx] = NULL;
701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
703 * mpt_event_register - Register protocol-specific event callback handler.
704 * @cb_idx: previously registered (via mpt_register) callback handle
705 * @ev_cbfunc: callback function
707 * This routine can be called by one or more protocol-specific drivers
708 * if/when they choose to be notified of MPT events.
710 * Returns 0 for success.
713 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
715 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
718 MptEvHandlers[cb_idx] = ev_cbfunc;
722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
724 * mpt_event_deregister - Deregister protocol-specific event callback handler
725 * @cb_idx: previously registered callback handle
727 * Each protocol-specific driver should call this routine
728 * when it does not (or can no longer) handle events,
729 * or when its module is unloaded.
732 mpt_event_deregister(u8 cb_idx)
734 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
737 MptEvHandlers[cb_idx] = NULL;
740 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
742 * mpt_reset_register - Register protocol-specific IOC reset handler.
743 * @cb_idx: previously registered (via mpt_register) callback handle
744 * @reset_func: reset function
746 * This routine can be called by one or more protocol-specific drivers
747 * if/when they choose to be notified of IOC resets.
749 * Returns 0 for success.
752 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
754 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
757 MptResetHandlers[cb_idx] = reset_func;
761 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
763 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
764 * @cb_idx: previously registered callback handle
766 * Each protocol-specific driver should call this routine
767 * when it does not (or can no longer) handle IOC reset handling,
768 * or when its module is unloaded.
771 mpt_reset_deregister(u8 cb_idx)
773 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
776 MptResetHandlers[cb_idx] = NULL;
779 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
781 * mpt_device_driver_register - Register device driver hooks
782 * @dd_cbfunc: driver callbacks struct
783 * @cb_idx: MPT protocol driver index
786 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
789 const struct pci_device_id *id;
791 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
794 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
796 /* call per pci device probe entry point */
797 list_for_each_entry(ioc, &ioc_list, list) {
798 if (!pci_get_drvdata(ioc->pcidev))
800 id = ioc->pcidev->driver ?
801 ioc->pcidev->driver->id_table : NULL;
802 if (dd_cbfunc->probe)
803 dd_cbfunc->probe(ioc->pcidev, id);
809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
811 * mpt_device_driver_deregister - DeRegister device driver hooks
812 * @cb_idx: MPT protocol driver index
815 mpt_device_driver_deregister(u8 cb_idx)
817 struct mpt_pci_driver *dd_cbfunc;
820 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
823 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
825 list_for_each_entry(ioc, &ioc_list, list) {
826 if (dd_cbfunc->remove)
827 dd_cbfunc->remove(ioc->pcidev);
830 MptDeviceDriverHandlers[cb_idx] = NULL;
834 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
836 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
837 * @cb_idx: Handle of registered MPT protocol driver
838 * @ioc: Pointer to MPT adapter structure
840 * Obtain an MPT request frame from the pool (of 1024) that are
841 * allocated per MPT adapter.
843 * Returns pointer to a MPT request frame or %NULL if none are available
844 * or IOC is not active.
847 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
851 u16 req_idx; /* Request index */
853 /* validate handle and ioc identifier */
857 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
858 "returning NULL!\n", ioc->name);
861 /* If interrupts are not attached, do not return a request frame */
865 spin_lock_irqsave(&ioc->FreeQlock, flags);
866 if (!list_empty(&ioc->FreeQ)) {
869 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
870 u.frame.linkage.list);
871 list_del(&mf->u.frame.linkage.list);
872 mf->u.frame.linkage.arg1 = 0;
873 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
874 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
876 req_idx = req_offset / ioc->req_sz;
877 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
878 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
879 /* Default, will be changed if necessary in SG generation */
880 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
887 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
891 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
892 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
895 if (mfcounter == PRINT_MF_COUNT)
896 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
897 ioc->mfcnt, ioc->req_depth);
900 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
901 ioc->name, cb_idx, ioc->id, mf));
905 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
907 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
908 * @cb_idx: Handle of registered MPT protocol driver
909 * @ioc: Pointer to MPT adapter structure
910 * @mf: Pointer to MPT request frame
912 * This routine posts an MPT request frame to the request post FIFO of a
913 * specific MPT adapter.
916 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
920 u16 req_idx; /* Request index */
922 /* ensure values are reset properly! */
923 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
924 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
926 req_idx = req_offset / ioc->req_sz;
927 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
928 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
930 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
932 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) |
933 ioc->RequestNB[req_idx];
934 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
935 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
936 ioc->RequestNB[req_idx]));
937 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
941 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
942 * @cb_idx: Handle of registered MPT protocol driver
943 * @ioc: Pointer to MPT adapter structure
944 * @mf: Pointer to MPT request frame
946 * Send a protocol-specific MPT request frame to an IOC using
947 * hi-priority request queue.
949 * This routine posts an MPT request frame to the request post FIFO of a
950 * specific MPT adapter.
953 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
957 u16 req_idx; /* Request index */
959 /* ensure values are reset properly! */
960 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
961 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
962 req_idx = req_offset / ioc->req_sz;
963 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
964 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
966 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
968 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
969 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
970 ioc->name, mf_dma_addr, req_idx));
971 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
974 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
976 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
977 * @ioc: Pointer to MPT adapter structure
978 * @mf: Pointer to MPT request frame
980 * This routine places a MPT request frame back on the MPT adapter's
984 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
988 /* Put Request back on FreeQ! */
989 spin_lock_irqsave(&ioc->FreeQlock, flags);
990 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
992 /* signature to know if this mf is freed */
993 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
994 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
999 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1002 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1004 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1005 * @pAddr: virtual address for SGE
1006 * @flagslength: SGE flags and data transfer length
1007 * @dma_addr: Physical address
1009 * This routine places a MPT request frame back on the MPT adapter's
1013 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1015 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1016 pSge->FlagsLength = cpu_to_le32(flagslength);
1017 pSge->Address = cpu_to_le32(dma_addr);
1021 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1022 * @pAddr: virtual address for SGE
1023 * @flagslength: SGE flags and data transfer length
1024 * @dma_addr: Physical address
1026 * This routine places a MPT request frame back on the MPT adapter's
1030 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1032 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1033 pSge->Address.Low = cpu_to_le32
1034 (lower_32_bits(dma_addr));
1035 pSge->Address.High = cpu_to_le32
1036 (upper_32_bits(dma_addr));
1037 pSge->FlagsLength = cpu_to_le32
1038 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1042 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr
1043 * (1078 workaround).
1044 * @pAddr: virtual address for SGE
1045 * @flagslength: SGE flags and data transfer length
1046 * @dma_addr: Physical address
1048 * This routine places a MPT request frame back on the MPT adapter's
1052 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1054 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1057 pSge->Address.Low = cpu_to_le32
1058 (lower_32_bits(dma_addr));
1059 tmp = (u32)(upper_32_bits(dma_addr));
1062 * 1078 errata workaround for the 36GB limitation
1064 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1066 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1068 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1069 printk(KERN_DEBUG "1078 P0M2 addressing for "
1070 "addr = 0x%llx len = %d\n",
1071 (unsigned long long)dma_addr,
1072 MPI_SGE_LENGTH(flagslength));
1075 pSge->Address.High = cpu_to_le32(tmp);
1076 pSge->FlagsLength = cpu_to_le32(
1077 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1082 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1083 * @pAddr: virtual address for SGE
1084 * @next: nextChainOffset value (u32's)
1085 * @length: length of next SGL segment
1086 * @dma_addr: Physical address
1090 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1092 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1093 pChain->Length = cpu_to_le16(length);
1094 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1095 pChain->NextChainOffset = next;
1096 pChain->Address = cpu_to_le32(dma_addr);
1099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1101 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1102 * @pAddr: virtual address for SGE
1103 * @next: nextChainOffset value (u32's)
1104 * @length: length of next SGL segment
1105 * @dma_addr: Physical address
1109 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1111 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1112 u32 tmp = dma_addr & 0xFFFFFFFF;
1114 pChain->Length = cpu_to_le16(length);
1115 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1116 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1118 pChain->NextChainOffset = next;
1120 pChain->Address.Low = cpu_to_le32(tmp);
1121 tmp = (u32)(upper_32_bits(dma_addr));
1122 pChain->Address.High = cpu_to_le32(tmp);
1125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1127 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1128 * @cb_idx: Handle of registered MPT protocol driver
1129 * @ioc: Pointer to MPT adapter structure
1130 * @reqBytes: Size of the request in bytes
1131 * @req: Pointer to MPT request frame
1132 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1134 * This routine is used exclusively to send MptScsiTaskMgmt
1135 * requests since they are required to be sent via doorbell handshake.
1137 * NOTE: It is the callers responsibility to byte-swap fields in the
1138 * request which are greater than 1 byte in size.
1140 * Returns 0 for success, non-zero for failure.
1143 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1149 /* State is known to be good upon entering
1150 * this function so issue the bus reset
1155 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1156 * setting cb_idx/req_idx. But ONLY if this request
1157 * is in proper (pre-alloc'd) request buffer range...
1159 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1160 if (ii >= 0 && ii < ioc->req_depth) {
1161 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1162 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1163 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1166 /* Make sure there are no doorbells */
1167 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1169 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1170 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1171 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1173 /* Wait for IOC doorbell int */
1174 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1178 /* Read doorbell and check for active bit */
1179 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1182 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1185 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1187 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1191 /* Send request via doorbell handshake */
1192 req_as_bytes = (u8 *) req;
1193 for (ii = 0; ii < reqBytes/4; ii++) {
1196 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1197 (req_as_bytes[(ii*4) + 1] << 8) |
1198 (req_as_bytes[(ii*4) + 2] << 16) |
1199 (req_as_bytes[(ii*4) + 3] << 24));
1200 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1201 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1207 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1212 /* Make sure there are no doorbells */
1213 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1218 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1220 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1221 * @ioc: Pointer to MPT adapter structure
1222 * @access_control_value: define bits below
1223 * @sleepFlag: Specifies whether the process can sleep
1225 * Provides mechanism for the host driver to control the IOC's
1226 * Host Page Buffer access.
1228 * Access Control Value - bits[15:12]
1230 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1231 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1232 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1234 * Returns 0 for success, non-zero for failure.
1238 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1242 /* return if in use */
1243 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1244 & MPI_DOORBELL_ACTIVE)
1247 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1249 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1250 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1251 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1252 (access_control_value<<12)));
1254 /* Wait for IOC to clear Doorbell Status bit */
1255 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1263 * mpt_host_page_alloc - allocate system memory for the fw
1264 * @ioc: Pointer to pointer to IOC adapter
1265 * @ioc_init: Pointer to ioc init config page
1267 * If we already allocated memory in past, then resend the same pointer.
1268 * Returns 0 for success, non-zero for failure.
1271 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1275 u32 host_page_buffer_sz=0;
1277 if(!ioc->HostPageBuffer) {
1279 host_page_buffer_sz =
1280 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1282 if(!host_page_buffer_sz)
1283 return 0; /* fw doesn't need any host buffers */
1285 /* spin till we get enough memory */
1286 while(host_page_buffer_sz > 0) {
1288 if((ioc->HostPageBuffer = pci_alloc_consistent(
1290 host_page_buffer_sz,
1291 &ioc->HostPageBuffer_dma)) != NULL) {
1293 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1294 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1295 ioc->name, ioc->HostPageBuffer,
1296 (u32)ioc->HostPageBuffer_dma,
1297 host_page_buffer_sz));
1298 ioc->alloc_total += host_page_buffer_sz;
1299 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1303 host_page_buffer_sz -= (4*1024);
1307 if(!ioc->HostPageBuffer) {
1308 printk(MYIOC_s_ERR_FMT
1309 "Failed to alloc memory for host_page_buffer!\n",
1314 psge = (char *)&ioc_init->HostPageBufferSGE;
1315 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1316 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1317 MPI_SGE_FLAGS_HOST_TO_IOC |
1318 MPI_SGE_FLAGS_END_OF_BUFFER;
1319 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1320 flags_length |= ioc->HostPageBuffer_sz;
1321 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1322 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1327 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1329 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1330 * @iocid: IOC unique identifier (integer)
1331 * @iocpp: Pointer to pointer to IOC adapter
1333 * Given a unique IOC identifier, set pointer to the associated MPT
1334 * adapter structure.
1336 * Returns iocid and sets iocpp if iocid is found.
1337 * Returns -1 if iocid is not found.
1340 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1344 list_for_each_entry(ioc,&ioc_list,list) {
1345 if (ioc->id == iocid) {
1356 * mpt_get_product_name - returns product string
1357 * @vendor: pci vendor id
1358 * @device: pci device id
1359 * @revision: pci revision id
1360 * @prod_name: string returned
1362 * Returns product string displayed when driver loads,
1363 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1367 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1369 char *product_str = NULL;
1371 if (vendor == PCI_VENDOR_ID_BROCADE) {
1374 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1378 product_str = "BRE040 A0";
1381 product_str = "BRE040 A1";
1384 product_str = "BRE040";
1394 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1395 product_str = "LSIFC909 B1";
1397 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1398 product_str = "LSIFC919 B0";
1400 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1401 product_str = "LSIFC929 B0";
1403 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1404 if (revision < 0x80)
1405 product_str = "LSIFC919X A0";
1407 product_str = "LSIFC919XL A1";
1409 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1410 if (revision < 0x80)
1411 product_str = "LSIFC929X A0";
1413 product_str = "LSIFC929XL A1";
1415 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1416 product_str = "LSIFC939X A1";
1418 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1419 product_str = "LSIFC949X A1";
1421 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1425 product_str = "LSIFC949E A0";
1428 product_str = "LSIFC949E A1";
1431 product_str = "LSIFC949E";
1435 case MPI_MANUFACTPAGE_DEVID_53C1030:
1439 product_str = "LSI53C1030 A0";
1442 product_str = "LSI53C1030 B0";
1445 product_str = "LSI53C1030 B1";
1448 product_str = "LSI53C1030 B2";
1451 product_str = "LSI53C1030 C0";
1454 product_str = "LSI53C1030T A0";
1457 product_str = "LSI53C1030T A2";
1460 product_str = "LSI53C1030T A3";
1463 product_str = "LSI53C1020A A1";
1466 product_str = "LSI53C1030";
1470 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1474 product_str = "LSI53C1035 A2";
1477 product_str = "LSI53C1035 B0";
1480 product_str = "LSI53C1035";
1484 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1488 product_str = "LSISAS1064 A1";
1491 product_str = "LSISAS1064 A2";
1494 product_str = "LSISAS1064 A3";
1497 product_str = "LSISAS1064 A4";
1500 product_str = "LSISAS1064";
1504 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1508 product_str = "LSISAS1064E A0";
1511 product_str = "LSISAS1064E B0";
1514 product_str = "LSISAS1064E B1";
1517 product_str = "LSISAS1064E B2";
1520 product_str = "LSISAS1064E B3";
1523 product_str = "LSISAS1064E";
1527 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1531 product_str = "LSISAS1068 A0";
1534 product_str = "LSISAS1068 B0";
1537 product_str = "LSISAS1068 B1";
1540 product_str = "LSISAS1068";
1544 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1548 product_str = "LSISAS1068E A0";
1551 product_str = "LSISAS1068E B0";
1554 product_str = "LSISAS1068E B1";
1557 product_str = "LSISAS1068E B2";
1560 product_str = "LSISAS1068E B3";
1563 product_str = "LSISAS1068E";
1567 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1571 product_str = "LSISAS1078 A0";
1574 product_str = "LSISAS1078 B0";
1577 product_str = "LSISAS1078 C0";
1580 product_str = "LSISAS1078 C1";
1583 product_str = "LSISAS1078 C2";
1586 product_str = "LSISAS1078";
1594 sprintf(prod_name, "%s", product_str);
1598 * mpt_mapresources - map in memory mapped io
1599 * @ioc: Pointer to pointer to IOC adapter
1602 #define convert_to_kb(x) ((x) << (PAGE_SHIFT - 10))
1604 mpt_mapresources(MPT_ADAPTER *ioc)
1608 resource_size_t mem_phys;
1613 struct pci_dev *pdev;
1617 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1618 if (pci_enable_device_mem(pdev)) {
1619 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1620 "failed\n", ioc->name);
1623 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1624 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1625 "MEM failed\n", ioc->name);
1629 if (sizeof(dma_addr_t) > 4) {
1630 uint64_t required_mask;
1632 required_mask = dma_get_required_mask(&pdev->dev);
1634 if (required_mask > DMA_BIT_MASK(32)
1635 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1636 && !pci_set_consistent_dma_mask(pdev,
1637 DMA_BIT_MASK(64))) {
1638 ioc->dma_mask = DMA_BIT_MASK(64);
1639 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1640 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1642 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1643 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1644 ioc->dma_mask = DMA_BIT_MASK(32);
1645 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1646 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1649 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1650 ioc->name, pci_name(pdev));
1654 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1655 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1656 ioc->dma_mask = DMA_BIT_MASK(32);
1657 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1658 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1661 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1662 ioc->name, pci_name(pdev));
1668 printk(MYIOC_s_INFO_FMT "%s BIT PCI BUS DMA ADDRESSING SUPPORTED, "
1669 "total memory = %ld kB\n",
1670 ioc->name, ioc->dma_mask == DMA_BIT_MASK(64) ? "64" : "32",
1671 convert_to_kb(s.totalram));
1672 mem_phys = msize = 0;
1674 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1675 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1678 /* Get I/O space! */
1679 port = pci_resource_start(pdev, ii);
1680 psize = pci_resource_len(pdev, ii);
1685 mem_phys = pci_resource_start(pdev, ii);
1686 msize = pci_resource_len(pdev, ii);
1689 ioc->mem_size = msize;
1692 /* Get logical ptr for PciMem0 space */
1693 /*mem = ioremap(mem_phys, msize);*/
1694 mem = ioremap(mem_phys, msize);
1696 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1697 " memory!\n", ioc->name);
1701 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1702 ioc->name, mem, (unsigned long long)mem_phys));
1704 ioc->mem_phys = mem_phys;
1705 ioc->chip = (SYSIF_REGS __iomem *)mem;
1707 /* Save Port IO values in case we need to do downloadboot */
1708 ioc->pio_mem_phys = port;
1709 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1714 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1716 * mpt_attach - Install a PCI intelligent MPT adapter.
1717 * @pdev: Pointer to pci_dev structure
1718 * @id: PCI device ID information
1720 * This routine performs all the steps necessary to bring the IOC of
1721 * a MPT adapter to a OPERATIONAL state. This includes registering
1722 * memory regions, registering the interrupt, and allocating request
1723 * and reply memory pools.
1725 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1728 * Returns 0 for success, non-zero for failure.
1730 * TODO: Add support for polled controllers
1733 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1740 static int mpt_ids = 0;
1741 #ifdef CONFIG_PROC_FS
1742 struct proc_dir_entry *dent, *ent;
1745 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1747 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1751 ioc->id = mpt_ids++;
1752 sprintf(ioc->name, "ioc%d", ioc->id);
1753 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1756 * set initial debug level
1757 * (refer to mptdebug.h)
1760 ioc->debug_level = mpt_debug_level;
1761 if (mpt_debug_level)
1762 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1764 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1767 if (mpt_mapresources(ioc)) {
1773 * Setting up proper handlers for scatter gather handling
1775 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1776 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1777 ioc->add_sge = &mpt_add_sge_64bit_1078;
1779 ioc->add_sge = &mpt_add_sge_64bit;
1780 ioc->add_chain = &mpt_add_chain_64bit;
1781 ioc->sg_addr_size = 8;
1783 ioc->add_sge = &mpt_add_sge;
1784 ioc->add_chain = &mpt_add_chain;
1785 ioc->sg_addr_size = 4;
1787 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1789 ioc->alloc_total = sizeof(MPT_ADAPTER);
1790 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1791 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1795 spin_lock_init(&ioc->taskmgmt_lock);
1796 mutex_init(&ioc->internal_cmds.mutex);
1797 init_completion(&ioc->internal_cmds.done);
1798 mutex_init(&ioc->mptbase_cmds.mutex);
1799 init_completion(&ioc->mptbase_cmds.done);
1800 mutex_init(&ioc->taskmgmt_cmds.mutex);
1801 init_completion(&ioc->taskmgmt_cmds.done);
1803 /* Initialize the event logging.
1805 ioc->eventTypes = 0; /* None */
1806 ioc->eventContext = 0;
1807 ioc->eventLogSize = 0;
1815 ioc->cached_fw = NULL;
1817 /* Initilize SCSI Config Data structure
1819 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1821 /* Initialize the fc rport list head.
1823 INIT_LIST_HEAD(&ioc->fc_rports);
1825 /* Find lookup slot. */
1826 INIT_LIST_HEAD(&ioc->list);
1828 /* Initialize workqueue */
1829 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1831 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1832 "mpt_poll_%d", ioc->id);
1834 create_singlethread_workqueue(ioc->reset_work_q_name);
1835 if (!ioc->reset_work_q) {
1836 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1838 pci_release_selected_regions(pdev, ioc->bars);
1843 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1844 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1846 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1847 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1849 switch (pdev->device)
1851 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1852 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1853 ioc->errata_flag_1064 = 1;
1854 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1855 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1856 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1857 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1861 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1862 if (revision < XL_929) {
1863 /* 929X Chip Fix. Set Split transactions level
1864 * for PCIX. Set MOST bits to zero.
1866 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1868 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1870 /* 929XL Chip Fix. Set MMRBC to 0x08.
1872 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1874 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1879 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1880 /* 919X Chip Fix. Set Split transactions level
1881 * for PCIX. Set MOST bits to zero.
1883 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1885 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1889 case MPI_MANUFACTPAGE_DEVID_53C1030:
1890 /* 1030 Chip Fix. Disable Split transactions
1891 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1893 if (revision < C0_1030) {
1894 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1896 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1899 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1900 ioc->bus_type = SPI;
1903 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1904 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1905 ioc->errata_flag_1064 = 1;
1906 ioc->bus_type = SAS;
1909 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1910 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1911 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1912 ioc->bus_type = SAS;
1917 switch (ioc->bus_type) {
1920 ioc->msi_enable = mpt_msi_enable_sas;
1924 ioc->msi_enable = mpt_msi_enable_spi;
1928 ioc->msi_enable = mpt_msi_enable_fc;
1932 ioc->msi_enable = 0;
1935 if (ioc->errata_flag_1064)
1936 pci_disable_io_access(pdev);
1938 spin_lock_init(&ioc->FreeQlock);
1941 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1943 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1945 /* Set IOC ptr in the pcidev's driver data. */
1946 pci_set_drvdata(ioc->pcidev, ioc);
1948 /* Set lookup ptr. */
1949 list_add_tail(&ioc->list, &ioc_list);
1951 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1953 mpt_detect_bound_ports(ioc, pdev);
1955 INIT_LIST_HEAD(&ioc->fw_event_list);
1956 spin_lock_init(&ioc->fw_event_lock);
1957 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1958 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1960 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1962 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1965 list_del(&ioc->list);
1967 ioc->alt_ioc->alt_ioc = NULL;
1968 iounmap(ioc->memmap);
1970 pci_release_selected_regions(pdev, ioc->bars);
1971 destroy_workqueue(ioc->reset_work_q);
1972 ioc->reset_work_q = NULL;
1975 pci_set_drvdata(pdev, NULL);
1979 /* call per device driver probe entry point */
1980 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1981 if(MptDeviceDriverHandlers[cb_idx] &&
1982 MptDeviceDriverHandlers[cb_idx]->probe) {
1983 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1987 #ifdef CONFIG_PROC_FS
1989 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1991 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1993 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1995 ent->read_proc = procmpt_iocinfo_read;
1998 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
2000 ent->read_proc = procmpt_summary_read;
2007 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2008 msecs_to_jiffies(MPT_POLLING_INTERVAL));
2013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2015 * mpt_detach - Remove a PCI intelligent MPT adapter.
2016 * @pdev: Pointer to pci_dev structure
2020 mpt_detach(struct pci_dev *pdev)
2022 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2025 unsigned long flags;
2026 struct workqueue_struct *wq;
2029 * Stop polling ioc for fault condition
2031 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2032 wq = ioc->reset_work_q;
2033 ioc->reset_work_q = NULL;
2034 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2035 cancel_delayed_work(&ioc->fault_reset_work);
2036 destroy_workqueue(wq);
2038 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2039 wq = ioc->fw_event_q;
2040 ioc->fw_event_q = NULL;
2041 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2042 destroy_workqueue(wq);
2044 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2045 remove_proc_entry(pname, NULL);
2046 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2047 remove_proc_entry(pname, NULL);
2048 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2049 remove_proc_entry(pname, NULL);
2051 /* call per device driver remove entry point */
2052 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2053 if(MptDeviceDriverHandlers[cb_idx] &&
2054 MptDeviceDriverHandlers[cb_idx]->remove) {
2055 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2059 /* Disable interrupts! */
2060 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2063 synchronize_irq(pdev->irq);
2065 /* Clear any lingering interrupt */
2066 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2068 CHIPREG_READ32(&ioc->chip->IntStatus);
2070 mpt_adapter_dispose(ioc);
2072 pci_set_drvdata(pdev, NULL);
2075 /**************************************************************************
2079 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2081 * mpt_suspend - Fusion MPT base driver suspend routine.
2082 * @pdev: Pointer to pci_dev structure
2083 * @state: new state to enter
2086 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2089 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2091 device_state = pci_choose_state(pdev, state);
2092 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2093 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2096 /* put ioc into READY_STATE */
2097 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2098 printk(MYIOC_s_ERR_FMT
2099 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2102 /* disable interrupts */
2103 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2106 /* Clear any lingering interrupt */
2107 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2109 free_irq(ioc->pci_irq, ioc);
2110 if (ioc->msi_enable)
2111 pci_disable_msi(ioc->pcidev);
2113 pci_save_state(pdev);
2114 pci_disable_device(pdev);
2115 pci_release_selected_regions(pdev, ioc->bars);
2116 pci_set_power_state(pdev, device_state);
2120 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2122 * mpt_resume - Fusion MPT base driver resume routine.
2123 * @pdev: Pointer to pci_dev structure
2126 mpt_resume(struct pci_dev *pdev)
2128 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2129 u32 device_state = pdev->current_state;
2133 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2134 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2137 pci_set_power_state(pdev, PCI_D0);
2138 pci_enable_wake(pdev, PCI_D0, 0);
2139 pci_restore_state(pdev);
2141 err = mpt_mapresources(ioc);
2145 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2146 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2147 ioc->add_sge = &mpt_add_sge_64bit_1078;
2149 ioc->add_sge = &mpt_add_sge_64bit;
2150 ioc->add_chain = &mpt_add_chain_64bit;
2151 ioc->sg_addr_size = 8;
2154 ioc->add_sge = &mpt_add_sge;
2155 ioc->add_chain = &mpt_add_chain;
2156 ioc->sg_addr_size = 4;
2158 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2160 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2161 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2162 CHIPREG_READ32(&ioc->chip->Doorbell));
2165 * Errata workaround for SAS pci express:
2166 * Upon returning to the D0 state, the contents of the doorbell will be
2167 * stale data, and this will incorrectly signal to the host driver that
2168 * the firmware is ready to process mpt commands. The workaround is
2169 * to issue a diagnostic reset.
2171 if (ioc->bus_type == SAS && (pdev->device ==
2172 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2173 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2174 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2175 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2181 /* bring ioc to operational state */
2182 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2183 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2185 if (recovery_state != 0)
2186 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2187 "error:[%x]\n", ioc->name, recovery_state);
2189 printk(MYIOC_s_INFO_FMT
2190 "pci-resume: success\n", ioc->name);
2198 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2200 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2201 ioc->bus_type != SPI) ||
2202 (MptDriverClass[index] == MPTFC_DRIVER &&
2203 ioc->bus_type != FC) ||
2204 (MptDriverClass[index] == MPTSAS_DRIVER &&
2205 ioc->bus_type != SAS))
2206 /* make sure we only call the relevant reset handler
2209 return (MptResetHandlers[index])(ioc, reset_phase);
2212 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2214 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2215 * @ioc: Pointer to MPT adapter structure
2216 * @reason: Event word / reason
2217 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2219 * This routine performs all the steps necessary to bring the IOC
2220 * to a OPERATIONAL state.
2222 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2227 * -1 if failed to get board READY
2228 * -2 if READY but IOCFacts Failed
2229 * -3 if READY but PrimeIOCFifos Failed
2230 * -4 if READY but IOCInit Failed
2231 * -5 if failed to enable_device and/or request_selected_regions
2232 * -6 if failed to upload firmware
2235 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2237 int hard_reset_done = 0;
2238 int alt_ioc_ready = 0;
2243 int reset_alt_ioc_active = 0;
2244 int irq_allocated = 0;
2247 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2248 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2250 /* Disable reply interrupts (also blocks FreeQ) */
2251 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2255 if (ioc->alt_ioc->active ||
2256 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2257 reset_alt_ioc_active = 1;
2258 /* Disable alt-IOC's reply interrupts
2259 * (and FreeQ) for a bit
2261 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2263 ioc->alt_ioc->active = 0;
2268 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2271 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2272 if (hard_reset_done == -4) {
2273 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2276 if (reset_alt_ioc_active && ioc->alt_ioc) {
2277 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2278 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2279 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2280 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2281 ioc->alt_ioc->active = 1;
2285 printk(MYIOC_s_WARN_FMT
2286 "NOT READY WARNING!\n", ioc->name);
2292 /* hard_reset_done = 0 if a soft reset was performed
2293 * and 1 if a hard reset was performed.
2295 if (!hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2296 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2297 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": alt-ioc reply irq re-enabled\n",
2298 ioc->alt_ioc->name));
2299 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2300 ioc->alt_ioc->active = 1;
2301 reset_alt_ioc_active = 0;
2304 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2305 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2308 printk(MYIOC_s_WARN_FMT
2309 ": alt-ioc Not ready WARNING!\n",
2310 ioc->alt_ioc->name);
2313 for (ii=0; ii<5; ii++) {
2314 /* Get IOC facts! Allow 5 retries */
2315 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2321 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2322 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2324 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2325 MptDisplayIocCapabilities(ioc);
2328 if (alt_ioc_ready) {
2329 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2330 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2331 "Initial Alt IocFacts failed rc=%x\n",
2333 /* Retry - alt IOC was initialized once
2335 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2338 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2339 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2341 reset_alt_ioc_active = 0;
2342 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2343 MptDisplayIocCapabilities(ioc->alt_ioc);
2347 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2348 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2349 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2350 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2352 if (pci_enable_device(ioc->pcidev))
2354 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2360 * Device is reset now. It must have de-asserted the interrupt line
2361 * (if it was asserted) and it should be safe to register for the
2364 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2366 if (ioc->pcidev->irq) {
2367 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2368 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2371 ioc->msi_enable = 0;
2372 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2373 IRQF_SHARED, ioc->name, ioc);
2375 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2377 ioc->name, ioc->pcidev->irq);
2378 if (ioc->msi_enable)
2379 pci_disable_msi(ioc->pcidev);
2384 ioc->pci_irq = ioc->pcidev->irq;
2385 pci_set_master(ioc->pcidev); /* ?? */
2386 pci_set_drvdata(ioc->pcidev, ioc);
2387 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2388 "installed at interrupt %d\n", ioc->name,
2393 /* Prime reply & request queues!
2394 * (mucho alloc's) Must be done prior to
2395 * init as upper addresses are needed for init.
2396 * If fails, continue with alt-ioc processing
2398 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2400 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2403 /* May need to check/upload firmware & data here!
2404 * If fails, continue with alt-ioc processing
2406 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2408 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2411 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2412 printk(MYIOC_s_WARN_FMT
2413 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2414 ioc->alt_ioc->name, rc);
2416 reset_alt_ioc_active = 0;
2419 if (alt_ioc_ready) {
2420 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2422 reset_alt_ioc_active = 0;
2423 printk(MYIOC_s_WARN_FMT
2424 ": alt-ioc: (%d) init failure WARNING!\n",
2425 ioc->alt_ioc->name, rc);
2429 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2430 if (ioc->upload_fw) {
2431 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2432 "firmware upload required!\n", ioc->name));
2434 /* Controller is not operational, cannot do upload
2437 rc = mpt_do_upload(ioc, sleepFlag);
2439 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2441 * Maintain only one pointer to FW memory
2442 * so there will not be two attempt to
2443 * downloadboot onboard dual function
2444 * chips (mpt_adapter_disable,
2447 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2448 "mpt_upload: alt_%s has cached_fw=%p \n",
2449 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2450 ioc->cached_fw = NULL;
2453 printk(MYIOC_s_WARN_FMT
2454 "firmware upload failure!\n", ioc->name);
2461 /* Enable MPT base driver management of EventNotification
2462 * and EventAck handling.
2464 if ((ret == 0) && (!ioc->facts.EventState)) {
2465 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2466 "SendEventNotification\n",
2468 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2471 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2472 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2475 /* Enable! (reply interrupt) */
2476 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2479 if (rc == 0) { /* alt ioc */
2480 if (reset_alt_ioc_active && ioc->alt_ioc) {
2481 /* (re)Enable alt-IOC! (reply interrupt) */
2482 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2483 "reply irq re-enabled\n",
2484 ioc->alt_ioc->name));
2485 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2487 ioc->alt_ioc->active = 1;
2492 /* Add additional "reason" check before call to GetLanConfigPages
2493 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2494 * recursive scenario; GetLanConfigPages times out, timer expired
2495 * routine calls HardResetHandler, which calls into here again,
2496 * and we try GetLanConfigPages again...
2498 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2501 * Initalize link list for inactive raid volumes.
2503 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2504 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2506 switch (ioc->bus_type) {
2509 /* clear persistency table */
2510 if(ioc->facts.IOCExceptions &
2511 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2512 ret = mptbase_sas_persist_operation(ioc,
2513 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2520 mpt_findImVolumes(ioc);
2522 /* Check, and possibly reset, the coalescing value
2524 mpt_read_ioc_pg_1(ioc);
2529 if ((ioc->pfacts[0].ProtocolFlags &
2530 MPI_PORTFACTS_PROTOCOL_LAN) &&
2531 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2533 * Pre-fetch the ports LAN MAC address!
2534 * (LANPage1_t stuff)
2536 (void) GetLanConfigPages(ioc);
2537 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2538 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2539 "LanAddr = %02X:%02X:%02X"
2540 ":%02X:%02X:%02X\n",
2541 ioc->name, a[5], a[4],
2542 a[3], a[2], a[1], a[0]));
2547 /* Get NVRAM and adapter maximums from SPP 0 and 2
2549 mpt_GetScsiPortSettings(ioc, 0);
2551 /* Get version and length of SDP 1
2553 mpt_readScsiDevicePageHeaders(ioc, 0);
2557 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2558 mpt_findImVolumes(ioc);
2560 /* Check, and possibly reset, the coalescing value
2562 mpt_read_ioc_pg_1(ioc);
2564 mpt_read_ioc_pg_4(ioc);
2569 GetIoUnitPage2(ioc);
2570 mpt_get_manufacturing_pg_0(ioc);
2574 if ((ret != 0) && irq_allocated) {
2575 free_irq(ioc->pci_irq, ioc);
2576 if (ioc->msi_enable)
2577 pci_disable_msi(ioc->pcidev);
2582 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2584 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2585 * @ioc: Pointer to MPT adapter structure
2586 * @pdev: Pointer to (struct pci_dev) structure
2588 * Search for PCI bus/dev_function which matches
2589 * PCI bus/dev_function (+/-1) for newly discovered 929,
2590 * 929X, 1030 or 1035.
2592 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2593 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2596 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2598 struct pci_dev *peer=NULL;
2599 unsigned int slot = PCI_SLOT(pdev->devfn);
2600 unsigned int func = PCI_FUNC(pdev->devfn);
2601 MPT_ADAPTER *ioc_srch;
2603 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2604 " searching for devfn match on %x or %x\n",
2605 ioc->name, pci_name(pdev), pdev->bus->number,
2606 pdev->devfn, func-1, func+1));
2608 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2610 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2615 list_for_each_entry(ioc_srch, &ioc_list, list) {
2616 struct pci_dev *_pcidev = ioc_srch->pcidev;
2617 if (_pcidev == peer) {
2618 /* Paranoia checks */
2619 if (ioc->alt_ioc != NULL) {
2620 printk(MYIOC_s_WARN_FMT
2621 "Oops, already bound (%s <==> %s)!\n",
2622 ioc->name, ioc->name, ioc->alt_ioc->name);
2624 } else if (ioc_srch->alt_ioc != NULL) {
2625 printk(MYIOC_s_WARN_FMT
2626 "Oops, already bound (%s <==> %s)!\n",
2627 ioc_srch->name, ioc_srch->name,
2628 ioc_srch->alt_ioc->name);
2631 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2632 "FOUND! binding %s <==> %s\n",
2633 ioc->name, ioc->name, ioc_srch->name));
2634 ioc_srch->alt_ioc = ioc;
2635 ioc->alt_ioc = ioc_srch;
2641 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2643 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2644 * @ioc: Pointer to MPT adapter structure
2647 mpt_adapter_disable(MPT_ADAPTER *ioc)
2652 if (ioc->cached_fw != NULL) {
2653 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2654 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2655 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2656 ioc->cached_fw, CAN_SLEEP)) < 0) {
2657 printk(MYIOC_s_WARN_FMT
2658 ": firmware downloadboot failure (%d)!\n",
2664 * Put the controller into ready state (if its not already)
2666 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2667 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2669 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2670 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2671 "reset failed to put ioc in ready state!\n",
2672 ioc->name, __FUNCTION__);
2674 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2675 "failed!\n", ioc->name, __FUNCTION__);
2678 /* Disable adapter interrupts! */
2679 synchronize_irq(ioc->pcidev->irq);
2680 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2683 /* Clear any lingering interrupt */
2684 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2685 CHIPREG_READ32(&ioc->chip->IntStatus);
2687 if (ioc->alloc != NULL) {
2689 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2690 ioc->name, ioc->alloc, ioc->alloc_sz));
2691 pci_free_consistent(ioc->pcidev, sz,
2692 ioc->alloc, ioc->alloc_dma);
2693 ioc->reply_frames = NULL;
2694 ioc->req_frames = NULL;
2696 ioc->alloc_total -= sz;
2699 if (ioc->sense_buf_pool != NULL) {
2700 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2701 pci_free_consistent(ioc->pcidev, sz,
2702 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2703 ioc->sense_buf_pool = NULL;
2704 ioc->alloc_total -= sz;
2707 if (ioc->events != NULL){
2708 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2711 ioc->alloc_total -= sz;
2714 mpt_free_fw_memory(ioc);
2716 kfree(ioc->spi_data.nvram);
2717 mpt_inactive_raid_list_free(ioc);
2718 kfree(ioc->raid_data.pIocPg2);
2719 kfree(ioc->raid_data.pIocPg3);
2720 kfree(ioc->raid_data.pIocPg6);
2721 ioc->spi_data.nvram = NULL;
2722 ioc->raid_data.pIocPg3 = NULL;
2723 ioc->raid_data.pIocPg6 = NULL;
2725 if (ioc->spi_data.pIocPg4 != NULL) {
2726 sz = ioc->spi_data.IocPg4Sz;
2727 pci_free_consistent(ioc->pcidev, sz,
2728 ioc->spi_data.pIocPg4,
2729 ioc->spi_data.IocPg4_dma);
2730 ioc->spi_data.pIocPg4 = NULL;
2731 ioc->alloc_total -= sz;
2734 if (ioc->ReqToChain != NULL) {
2735 kfree(ioc->ReqToChain);
2736 kfree(ioc->RequestNB);
2737 ioc->ReqToChain = NULL;
2740 kfree(ioc->ChainToChain);
2741 ioc->ChainToChain = NULL;
2743 if (ioc->HostPageBuffer != NULL) {
2744 if((ret = mpt_host_page_access_control(ioc,
2745 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2746 printk(MYIOC_s_ERR_FMT
2747 ": %s: host page buffers free failed (%d)!\n",
2748 ioc->name, __func__, ret);
2750 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2751 "HostPageBuffer free @ %p, sz=%d bytes\n",
2752 ioc->name, ioc->HostPageBuffer,
2753 ioc->HostPageBuffer_sz));
2754 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2755 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2756 ioc->HostPageBuffer = NULL;
2757 ioc->HostPageBuffer_sz = 0;
2758 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2761 pci_set_drvdata(ioc->pcidev, NULL);
2763 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2765 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2766 * @ioc: Pointer to MPT adapter structure
2768 * This routine unregisters h/w resources and frees all alloc'd memory
2769 * associated with a MPT adapter structure.
2772 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2774 int sz_first, sz_last;
2779 sz_first = ioc->alloc_total;
2781 mpt_adapter_disable(ioc);
2783 if (ioc->pci_irq != -1) {
2784 free_irq(ioc->pci_irq, ioc);
2785 if (ioc->msi_enable)
2786 pci_disable_msi(ioc->pcidev);
2790 if (ioc->memmap != NULL) {
2791 iounmap(ioc->memmap);
2795 pci_disable_device(ioc->pcidev);
2796 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2798 #if defined(CONFIG_MTRR) && 0
2799 if (ioc->mtrr_reg > 0) {
2800 mtrr_del(ioc->mtrr_reg, 0, 0);
2801 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2805 /* Zap the adapter lookup ptr! */
2806 list_del(&ioc->list);
2808 sz_last = ioc->alloc_total;
2809 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2810 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2813 ioc->alt_ioc->alt_ioc = NULL;
2818 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2820 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2821 * @ioc: Pointer to MPT adapter structure
2824 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2828 printk(KERN_INFO "%s: ", ioc->name);
2830 printk("%s: ", ioc->prod_name);
2831 printk("Capabilities={");
2833 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2834 printk("Initiator");
2838 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2839 printk("%sTarget", i ? "," : "");
2843 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2844 printk("%sLAN", i ? "," : "");
2850 * This would probably evoke more questions than it's worth
2852 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2853 printk("%sLogBusAddr", i ? "," : "");
2861 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2863 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2864 * @ioc: Pointer to MPT_ADAPTER structure
2865 * @force: Force hard KickStart of IOC
2866 * @sleepFlag: Specifies whether the process can sleep
2869 * 1 - DIAG reset and READY
2870 * 0 - READY initially OR soft reset and READY
2871 * -1 - Any failure on KickStart
2872 * -2 - Msg Unit Reset Failed
2873 * -3 - IO Unit Reset Failed
2874 * -4 - IOC owned by a PEER
2877 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2882 int hard_reset_done = 0;
2887 /* Get current [raw] IOC state */
2888 ioc_state = mpt_GetIocState(ioc, 0);
2889 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2892 * Check to see if IOC got left/stuck in doorbell handshake
2893 * grip of death. If so, hard reset the IOC.
2895 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2897 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2901 /* Is it already READY? */
2903 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2904 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2905 "IOC is in READY state\n", ioc->name));
2910 * Check to see if IOC is in FAULT state.
2912 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2915 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2917 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2918 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2922 * Hmmm... Did it get left operational?
2924 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2925 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2929 * If PCI Peer, exit.
2930 * Else, if no fault conditions are present, issue a MessageUnitReset
2931 * Else, fall through to KickStart case
2933 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2934 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2935 "whoinit 0x%x statefault %d force %d\n",
2936 ioc->name, whoinit, statefault, force));
2937 if (whoinit == MPI_WHOINIT_PCI_PEER)
2940 if ((statefault == 0 ) && (force == 0)) {
2941 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2948 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2949 if (hard_reset_done < 0)
2953 * Loop here waiting for IOC to come READY.
2956 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2958 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2959 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2961 * BIOS or previous driver load left IOC in OP state.
2962 * Reset messaging FIFOs.
2964 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2965 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2968 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2970 * Something is wrong. Try to get IOC back
2973 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2974 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2981 printk(MYIOC_s_ERR_FMT
2982 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2983 ioc->name, ioc_state, (int)((ii+5)/HZ));
2987 if (sleepFlag == CAN_SLEEP) {
2990 mdelay (1); /* 1 msec delay */
2995 if (statefault < 3) {
2996 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
2997 statefault == 1 ? "stuck handshake" : "IOC FAULT");
3000 return hard_reset_done;
3003 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3005 * mpt_GetIocState - Get the current state of a MPT adapter.
3006 * @ioc: Pointer to MPT_ADAPTER structure
3007 * @cooked: Request raw or cooked IOC state
3009 * Returns all IOC Doorbell register bits if cooked==0, else just the
3010 * Doorbell bits in MPI_IOC_STATE_MASK.
3013 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
3018 s = CHIPREG_READ32(&ioc->chip->Doorbell);
3019 sc = s & MPI_IOC_STATE_MASK;
3022 ioc->last_state = sc;
3024 return cooked ? sc : s;
3027 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3029 * GetIocFacts - Send IOCFacts request to MPT adapter.
3030 * @ioc: Pointer to MPT_ADAPTER structure
3031 * @sleepFlag: Specifies whether the process can sleep
3032 * @reason: If recovery, only update facts.
3034 * Returns 0 for success, non-zero for failure.
3037 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3039 IOCFacts_t get_facts;
3040 IOCFactsReply_t *facts;
3048 /* IOC *must* NOT be in RESET state! */
3049 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3050 printk(KERN_ERR MYNAM
3051 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3052 ioc->name, ioc->last_state);
3056 facts = &ioc->facts;
3058 /* Destination (reply area)... */
3059 reply_sz = sizeof(*facts);
3060 memset(facts, 0, reply_sz);
3062 /* Request area (get_facts on the stack right now!) */
3063 req_sz = sizeof(get_facts);
3064 memset(&get_facts, 0, req_sz);
3066 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3067 /* Assert: All other get_facts fields are zero! */
3069 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3070 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3071 ioc->name, req_sz, reply_sz));
3073 /* No non-zero fields in the get_facts request are greater than
3074 * 1 byte in size, so we can just fire it off as is.
3076 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3077 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3082 * Now byte swap (GRRR) the necessary fields before any further
3083 * inspection of reply contents.
3085 * But need to do some sanity checks on MsgLength (byte) field
3086 * to make sure we don't zero IOC's req_sz!
3088 /* Did we get a valid reply? */
3089 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3090 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3092 * If not been here, done that, save off first WhoInit value
3094 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3095 ioc->FirstWhoInit = facts->WhoInit;
3098 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3099 if (facts->MsgVersion == MPI_VERSION_01_05)
3100 facts->HeaderVersion = le16_to_cpu(facts->HeaderVersion);
3101 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3102 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3103 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3104 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3105 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3106 /* CHECKME! IOCStatus, IOCLogInfo */
3108 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3109 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3112 * FC f/w version changed between 1.1 and 1.2
3113 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3114 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3116 if (facts->MsgVersion < MPI_VERSION_01_02) {
3118 * Handle old FC f/w style, convert to new...
3120 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3121 facts->FWVersion.Word =
3122 ((oldv<<12) & 0xFF000000) |
3123 ((oldv<<8) & 0x000FFF00);
3125 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3127 facts->ProductID = le16_to_cpu(facts->ProductID);
3129 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3130 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3131 ioc->ir_firmware = 1;
3133 facts->CurrentHostMfaHighAddr =
3134 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3135 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3136 facts->CurrentSenseBufferHighAddr =
3137 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3138 facts->CurReplyFrameSize =
3139 le16_to_cpu(facts->CurReplyFrameSize);
3140 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3143 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3144 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3145 * to 14 in MPI-1.01.0x.
3147 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3148 facts->MsgVersion > MPI_VERSION_01_00) {
3149 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3152 sz = facts->FWImageSize;
3157 facts->FWImageSize = sz;
3159 if (!facts->RequestFrameSize) {
3160 /* Something is wrong! */
3161 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3166 r = sz = facts->BlockSize;
3167 vv = ((63 / (sz * 4)) + 1) & 0x03;
3168 ioc->NB_for_64_byte_frame = vv;
3174 ioc->NBShiftFactor = shiftFactor;
3175 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3176 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3177 ioc->name, vv, shiftFactor, r));
3179 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3181 * Set values for this IOC's request & reply frame sizes,
3182 * and request & reply queue depths...
3184 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3185 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3186 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3187 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3189 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3190 ioc->name, ioc->reply_sz, ioc->reply_depth));
3191 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3192 ioc->name, ioc->req_sz, ioc->req_depth));
3194 /* Get port facts! */
3195 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3199 printk(MYIOC_s_ERR_FMT
3200 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3201 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3202 RequestFrameSize)/sizeof(u32)));
3209 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3211 * GetPortFacts - Send PortFacts request to MPT adapter.
3212 * @ioc: Pointer to MPT_ADAPTER structure
3213 * @portnum: Port number
3214 * @sleepFlag: Specifies whether the process can sleep
3216 * Returns 0 for success, non-zero for failure.
3219 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3221 PortFacts_t get_pfacts;
3222 PortFactsReply_t *pfacts;
3228 /* IOC *must* NOT be in RESET state! */
3229 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3230 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3231 ioc->name, ioc->last_state );
3235 pfacts = &ioc->pfacts[portnum];
3237 /* Destination (reply area)... */
3238 reply_sz = sizeof(*pfacts);
3239 memset(pfacts, 0, reply_sz);
3241 /* Request area (get_pfacts on the stack right now!) */
3242 req_sz = sizeof(get_pfacts);
3243 memset(&get_pfacts, 0, req_sz);
3245 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3246 get_pfacts.PortNumber = portnum;
3247 /* Assert: All other get_pfacts fields are zero! */
3249 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3250 ioc->name, portnum));
3252 /* No non-zero fields in the get_pfacts request are greater than
3253 * 1 byte in size, so we can just fire it off as is.
3255 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3256 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3260 /* Did we get a valid reply? */
3262 /* Now byte swap the necessary fields in the response. */
3263 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3264 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3265 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3266 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3267 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3268 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3269 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3270 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3271 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3273 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3275 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3276 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3279 * Place all the devices on channels
3283 if (mpt_channel_mapping) {
3284 ioc->devices_per_bus = 1;
3285 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3291 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3293 * SendIocInit - Send IOCInit request to MPT adapter.
3294 * @ioc: Pointer to MPT_ADAPTER structure
3295 * @sleepFlag: Specifies whether the process can sleep
3297 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3299 * Returns 0 for success, non-zero for failure.
3302 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3305 MPIDefaultReply_t init_reply;
3311 memset(&ioc_init, 0, sizeof(ioc_init));
3312 memset(&init_reply, 0, sizeof(init_reply));
3314 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3315 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3317 /* If we are in a recovery mode and we uploaded the FW image,
3318 * then this pointer is not NULL. Skip the upload a second time.
3319 * Set this flag if cached_fw set for either IOC.
3321 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3325 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3326 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3328 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3329 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3331 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3332 ioc->name, ioc->facts.MsgVersion));
3333 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3334 // set MsgVersion and HeaderVersion host driver was built with
3335 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3336 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3338 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3339 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3340 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3343 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3345 if (ioc->sg_addr_size == sizeof(u64)) {
3346 /* Save the upper 32-bits of the request
3347 * (reply) and sense buffers.
3349 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3350 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3352 /* Force 32-bit addressing */
3353 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3354 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3357 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3358 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3359 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3360 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3362 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3363 ioc->name, &ioc_init));
3365 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3366 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3368 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3372 /* No need to byte swap the multibyte fields in the reply
3373 * since we don't even look at its contents.
3376 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3377 ioc->name, &ioc_init));
3379 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3380 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3384 /* YIKES! SUPER IMPORTANT!!!
3385 * Poll IocState until _OPERATIONAL while IOC is doing
3386 * LoopInit and TargetDiscovery!
3389 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3390 state = mpt_GetIocState(ioc, 1);
3391 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3392 if (sleepFlag == CAN_SLEEP) {
3399 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3400 ioc->name, (int)((count+5)/HZ));
3404 state = mpt_GetIocState(ioc, 1);
3407 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3410 ioc->aen_event_read_flag=0;
3414 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3416 * SendPortEnable - Send PortEnable request to MPT adapter port.
3417 * @ioc: Pointer to MPT_ADAPTER structure
3418 * @portnum: Port number to enable
3419 * @sleepFlag: Specifies whether the process can sleep
3421 * Send PortEnable to bring IOC to OPERATIONAL state.
3423 * Returns 0 for success, non-zero for failure.
3426 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3428 PortEnable_t port_enable;
3429 MPIDefaultReply_t reply_buf;
3434 /* Destination... */
3435 reply_sz = sizeof(MPIDefaultReply_t);
3436 memset(&reply_buf, 0, reply_sz);
3438 req_sz = sizeof(PortEnable_t);
3439 memset(&port_enable, 0, req_sz);
3441 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3442 port_enable.PortNumber = portnum;
3443 /* port_enable.ChainOffset = 0; */
3444 /* port_enable.MsgFlags = 0; */
3445 /* port_enable.MsgContext = 0; */
3447 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3448 ioc->name, portnum, &port_enable));
3450 /* RAID FW may take a long time to enable
3452 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3453 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3454 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3455 300 /*seconds*/, sleepFlag);
3457 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3458 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3459 30 /*seconds*/, sleepFlag);
3465 * mpt_alloc_fw_memory - allocate firmware memory
3466 * @ioc: Pointer to MPT_ADAPTER structure
3467 * @size: total FW bytes
3469 * If memory has already been allocated, the same (cached) value
3472 * Return 0 if successfull, or non-zero for failure
3475 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3479 if (ioc->cached_fw) {
3480 rc = 0; /* use already allocated memory */
3483 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3484 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3485 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3489 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3490 if (!ioc->cached_fw) {
3491 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3495 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3496 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3497 ioc->alloc_total += size;
3505 * mpt_free_fw_memory - free firmware memory
3506 * @ioc: Pointer to MPT_ADAPTER structure
3508 * If alt_img is NULL, delete from ioc structure.
3509 * Else, delete a secondary image in same format.
3512 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3516 if (!ioc->cached_fw)
3519 sz = ioc->facts.FWImageSize;
3520 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3521 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3522 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3523 ioc->alloc_total -= sz;
3524 ioc->cached_fw = NULL;
3527 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3529 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3530 * @ioc: Pointer to MPT_ADAPTER structure
3531 * @sleepFlag: Specifies whether the process can sleep
3533 * Returns 0 for success, >0 for handshake failure
3534 * <0 for fw upload failure.
3536 * Remark: If bound IOC and a successful FWUpload was performed
3537 * on the bound IOC, the second image is discarded
3538 * and memory is free'd. Both channels must upload to prevent
3539 * IOC from running in degraded mode.
3542 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3544 u8 reply[sizeof(FWUploadReply_t)];
3545 FWUpload_t *prequest;
3546 FWUploadReply_t *preply;
3547 FWUploadTCSGE_t *ptcsge;
3549 int ii, sz, reply_sz;
3553 /* If the image size is 0, we are done.
3555 sz = ioc->facts.FWImageSize;
3559 if (mpt_alloc_fw_memory(ioc, sz) != 0)
3562 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3563 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3565 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3566 kzalloc(ioc->req_sz, GFP_KERNEL);
3568 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3569 "while allocating memory \n", ioc->name));
3570 mpt_free_fw_memory(ioc);
3574 preply = (FWUploadReply_t *)&reply;
3576 reply_sz = sizeof(reply);
3577 memset(preply, 0, reply_sz);
3579 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3580 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3582 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3583 ptcsge->DetailsLength = 12;
3584 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3585 ptcsge->ImageSize = cpu_to_le32(sz);
3588 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3589 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3590 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3592 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3593 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3595 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3597 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3598 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3600 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3601 "rc=%x \n", ioc->name, ii));
3603 cmdStatus = -EFAULT;
3605 /* Handshake transfer was complete and successful.
3606 * Check the Reply Frame.
3609 status = le16_to_cpu(preply->IOCStatus) &
3611 if ((status == MPI_IOCSTATUS_SUCCESS) &&
3612 (ioc->facts.FWImageSize ==
3613 le32_to_cpu(preply->ActualImageSize)))
3616 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3617 ioc->name, cmdStatus));
3621 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3622 "freeing image \n", ioc->name));
3623 mpt_free_fw_memory(ioc);
3630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3632 * mpt_downloadboot - DownloadBoot code
3633 * @ioc: Pointer to MPT_ADAPTER structure
3634 * @pFwHeader: Pointer to firmware header info
3635 * @sleepFlag: Specifies whether the process can sleep
3637 * FwDownloadBoot requires Programmed IO access.
3639 * Returns 0 for success
3640 * -1 FW Image size is 0
3641 * -2 No valid cached_fw Pointer
3642 * <0 for fw upload failure.
3645 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3647 MpiExtImageHeader_t *pExtImage;
3657 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3658 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3660 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3661 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3662 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3663 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3664 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3665 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3667 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3670 if (sleepFlag == CAN_SLEEP) {
3676 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3677 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3679 for (count = 0; count < 30; count ++) {
3680 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3681 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3682 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3687 if (sleepFlag == CAN_SLEEP) {
3694 if ( count == 30 ) {
3695 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3696 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3697 ioc->name, diag0val));
3701 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3702 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3703 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3704 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3705 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3706 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3708 /* Set the DiagRwEn and Disable ARM bits */
3709 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3710 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3712 fwSize = (pFwHeader->ImageSize + 3)/4;
3713 ptrFw = (u32 *) pFwHeader;
3715 /* Write the LoadStartAddress to the DiagRw Address Register
3716 * using Programmed IO
3718 if (ioc->errata_flag_1064)
3719 pci_enable_io_access(ioc->pcidev);
3721 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3722 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3723 ioc->name, pFwHeader->LoadStartAddress));
3725 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3726 ioc->name, fwSize*4, ptrFw));
3728 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3731 nextImage = pFwHeader->NextImageHeaderOffset;
3733 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3735 load_addr = pExtImage->LoadStartAddress;
3737 fwSize = (pExtImage->ImageSize + 3) >> 2;
3738 ptrFw = (u32 *)pExtImage;
3740 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3741 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3742 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3745 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3747 nextImage = pExtImage->NextImageHeaderOffset;
3750 /* Write the IopResetVectorRegAddr */
3751 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n",
3752 ioc->name, pFwHeader->IopResetRegAddr));
3753 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3755 /* Write the IopResetVectorValue */
3756 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n",
3757 ioc->name, pFwHeader->IopResetVectorValue));
3758 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3760 /* Clear the internal flash bad bit - autoincrementing register,
3761 * so must do two writes.
3763 if (ioc->bus_type == SPI) {
3765 * 1030 and 1035 H/W errata, workaround to access
3766 * the ClearFlashBadSignatureBit
3768 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3769 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3770 diagRwData |= 0x40000000;
3771 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3772 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3776 if (ioc->errata_flag_1064)
3777 pci_disable_io_access(ioc->pcidev);
3779 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3780 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3781 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3782 ioc->name, diag0val));
3783 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
3784 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3785 ioc->name, diag0val));
3786 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3788 if (ioc->bus_type == SAS ) {
3790 if (sleepFlag == CAN_SLEEP)
3795 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3796 ddlprintk(ioc, printk (MYIOC_s_DEBUG_FMT
3797 "diag0val=%x, turning off RW_ENABLE\n", ioc->name,
3799 diag0val &= ~(MPI_DIAG_RW_ENABLE);
3800 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3801 "now diag0val=%x\n", ioc->name, diag0val));
3802 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3804 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3805 if (diag0val & MPI_DIAG_FLASH_BAD_SIG) {
3806 diag0val |= MPI_DIAG_CLEAR_FLASH_BAD_SIG;
3807 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3808 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3810 diag0val &= ~(MPI_DIAG_DISABLE_ARM);
3811 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3812 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3813 CHIPREG_WRITE32(&ioc->chip->DiagRwAddress, 0x3f000004);
3816 /* Write 0xFF to reset the sequencer */
3817 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3819 for (count = 0; count < 30; count ++) {
3820 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_IOC_STATE_MASK;
3821 if (doorbell == MPI_IOC_STATE_READY) {
3822 if (ioc->bus_type == SAS)
3824 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3825 ddlprintk(ioc, printk(MYIOC_s_WARN_FMT
3826 "SendIocInit failed\n", ioc->name));
3829 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3830 "SendIocInit successful\n", ioc->name));
3833 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "looking for READY STATE:"
3834 " doorbell=%x count=%d\n", ioc->name, doorbell, count));
3835 if (sleepFlag == CAN_SLEEP)
3840 ddlprintk(ioc, printk(MYIOC_s_WARN_FMT "downloadboot failed! count=%d\n", ioc->name, count));
3844 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3846 * KickStart - Perform hard reset of MPT adapter.
3847 * @ioc: Pointer to MPT_ADAPTER structure
3848 * @force: Force hard reset
3849 * @sleepFlag: Specifies whether the process can sleep
3851 * This routine places MPT adapter in diagnostic mode via the
3852 * WriteSequence register, and then performs a hard reset of adapter
3853 * via the Diagnostic register.
3855 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3856 * or NO_SLEEP (interrupt thread, use mdelay)
3857 * force - 1 if doorbell active, board fault state
3858 * board operational, IOC_RECOVERY or
3859 * IOC_BRINGUP and there is an alt_ioc.
3863 * 1 - hard reset, READY
3864 * 0 - no reset due to History bit, READY
3865 * -1 - no reset due to History bit but not READY
3866 * OR reset but failed to come READY
3867 * -2 - no reset, could not enter DIAG mode
3868 * -3 - reset but bad FW bit
3871 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3873 int hard_reset_done = 0;
3877 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3878 if (ioc->bus_type == SPI) {
3879 /* Always issue a Msg Unit Reset first. This will clear some
3880 * SCSI bus hang conditions.
3882 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3884 if (sleepFlag == CAN_SLEEP) {
3891 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3892 if (hard_reset_done < 0)
3893 return hard_reset_done;
3895 /* may not have worked but hard_reset_done doesn't always signal failure */
3896 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3899 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3900 for (cnt=0; cnt<cntdn; cnt++) {
3901 ioc_state = mpt_GetIocState(ioc, 1);
3902 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3903 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3905 return hard_reset_done;
3907 if (sleepFlag == CAN_SLEEP) {
3914 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3915 ioc->name, mpt_GetIocState(ioc, 0)));
3919 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3921 * mpt_diag_reset - Perform hard reset of the adapter.
3922 * @ioc: Pointer to MPT_ADAPTER structure
3923 * @ignore: Set if to honor and clear to ignore
3924 * the reset history bit
3925 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3926 * else set to NO_SLEEP (use mdelay instead)
3928 * This routine places the adapter in diagnostic mode via the
3929 * WriteSequence register and then performs a hard reset of adapter
3930 * via the Diagnostic register. Adapter should be in ready state
3931 * upon successful completion.
3933 * Returns: 1 hard reset successful
3934 * 0 no reset performed because reset history bit set
3935 * -2 enabling diagnostic mode failed
3936 * -3 diagnostic reset failed
3939 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3943 int hard_reset_done = 0;
3946 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3949 /* Clear any existing interrupts */
3950 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3952 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3957 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3958 "address=%p\n", ioc->name, __func__,
3959 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3960 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3961 if (sleepFlag == CAN_SLEEP)
3967 * Call each currently registered protocol IOC reset handler
3968 * with pre-reset indication.
3969 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3970 * MptResetHandlers[] registered yet.
3972 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3973 if (MptResetHandlers[cb_idx])
3974 (*(MptResetHandlers[cb_idx]))(ioc, MPT_IOC_PRE_RESET);
3977 for (count = 0; count < 60; count ++) {
3978 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3979 doorbell &= MPI_IOC_STATE_MASK;
3981 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3982 "looking for READY STATE: doorbell=%x"
3984 ioc->name, doorbell, count));
3986 if (doorbell == MPI_IOC_STATE_READY) {
3991 * Early out for hard fault
3993 if (count && doorbell == MPI_IOC_STATE_FAULT)
3997 if (sleepFlag == CAN_SLEEP)
4003 if (doorbell != MPI_IOC_STATE_READY)
4004 printk(MYIOC_s_ERR_FMT "Failed to come READY after "
4005 "reset! IocState=%x", ioc->name, doorbell);
4009 /* Use "Diagnostic reset" method! (only thing available!) */
4010 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4012 if (ioc->debug_level & MPT_DEBUG_RESET) {
4014 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4015 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
4016 ioc->name, diag0val, diag1val));
4019 /* Do the reset if we are told to ignore the reset history
4020 * or if the reset history is 0
4022 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
4023 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4024 /* Write magic sequence to WriteSequence register
4025 * Loop until in diagnostic mode
4027 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4028 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4029 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4030 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4031 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4032 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4035 if (sleepFlag == CAN_SLEEP) {
4043 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4044 ioc->name, diag0val);
4049 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4051 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4052 ioc->name, diag0val));
4055 if (ioc->debug_level & MPT_DEBUG_RESET) {
4057 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4058 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4059 ioc->name, diag0val, diag1val));
4062 * Disable the ARM (Bug fix)
4065 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4069 * Now hit the reset bit in the Diagnostic register
4070 * (THE BIG HAMMER!) (Clears DRWE bit).
4072 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4073 hard_reset_done = 1;
4074 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4078 * Call each currently registered protocol IOC reset handler
4079 * with pre-reset indication.
4080 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4081 * MptResetHandlers[] registered yet.
4083 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4084 if (MptResetHandlers[cb_idx]) {
4085 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
4087 mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
4093 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4094 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4095 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4099 /* If the DownloadBoot operation fails, the
4100 * IOC will be left unusable. This is a fatal error
4101 * case. _diag_reset will return < 0
4103 for (count = 0; count < 30; count ++) {
4104 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4105 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4109 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4110 ioc->name, diag0val, count));
4112 if (sleepFlag == CAN_SLEEP) {
4118 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4119 printk(MYIOC_s_WARN_FMT
4120 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4124 /* Wait for FW to reload and for board
4125 * to go to the READY state.
4126 * Maximum wait is 60 seconds.
4127 * If fail, no error will check again
4128 * with calling program.
4130 for (count = 0; count < 60; count ++) {
4131 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4132 doorbell &= MPI_IOC_STATE_MASK;
4134 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4135 "looking for READY STATE: doorbell=%x"
4136 " count=%d\n", ioc->name, doorbell, count));
4138 if (doorbell == MPI_IOC_STATE_READY) {
4143 * Early out for hard fault
4145 if (count && doorbell == MPI_IOC_STATE_FAULT)
4149 if (sleepFlag == CAN_SLEEP) {
4156 if (doorbell != MPI_IOC_STATE_READY)
4157 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4158 "after reset! IocState=%x", ioc->name,
4163 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4164 if (ioc->debug_level & MPT_DEBUG_RESET) {
4166 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4167 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4168 ioc->name, diag0val, diag1val));
4171 /* Clear RESET_HISTORY bit! Place board in the
4172 * diagnostic mode to update the diag register.
4174 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4176 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4177 /* Write magic sequence to WriteSequence register
4178 * Loop until in diagnostic mode
4180 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4181 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4182 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4183 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4184 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4185 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4188 if (sleepFlag == CAN_SLEEP) {
4196 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4197 ioc->name, diag0val);
4200 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4202 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4203 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4204 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4205 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4206 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4210 /* Disable Diagnostic Mode
4212 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4214 /* Check FW reload status flags.
4216 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4217 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4218 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4219 ioc->name, diag0val);
4223 if (ioc->debug_level & MPT_DEBUG_RESET) {
4225 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4226 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4227 ioc->name, diag0val, diag1val));
4231 * Reset flag that says we've enabled event notification
4233 ioc->facts.EventState = 0;
4236 ioc->alt_ioc->facts.EventState = 0;
4238 return hard_reset_done;
4241 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4243 * SendIocReset - Send IOCReset request to MPT adapter.
4244 * @ioc: Pointer to MPT_ADAPTER structure
4245 * @reset_type: reset type, expected values are
4246 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4247 * @sleepFlag: Specifies whether the process can sleep
4249 * Send IOCReset request to the MPT adapter.
4251 * Returns 0 for success, non-zero for failure.
4254 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4260 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4261 ioc->name, reset_type));
4262 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4263 if ((r = WaitForDoorbellAck(ioc, 15, sleepFlag)) < 0)
4266 /* FW ACK'd request, wait for READY state
4269 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4271 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4275 if (sleepFlag != CAN_SLEEP)
4278 printk(MYIOC_s_ERR_FMT
4279 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4280 ioc->name, state, (int)((count+5)/HZ));
4284 if (sleepFlag == CAN_SLEEP) {
4287 mdelay (1); /* 1 msec delay */
4292 * Cleanup all event stuff for this IOC; re-issue EventNotification
4293 * request if needed.
4295 if (ioc->facts.Function)
4296 ioc->facts.EventState = 0;
4301 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4303 * initChainBuffers - Allocate memory for and initialize chain buffers
4304 * @ioc: Pointer to MPT_ADAPTER structure
4306 * Allocates memory for and initializes chain buffers,
4307 * chain buffer control arrays and spinlock.
4310 initChainBuffers(MPT_ADAPTER *ioc)
4313 int sz, ii, num_chain;
4314 int scale, num_sge, numSGE;
4316 /* ReqToChain size must equal the req_depth
4319 if (ioc->ReqToChain == NULL) {
4320 sz = ioc->req_depth * sizeof(int);
4321 mem = kmalloc(sz, GFP_ATOMIC);
4325 ioc->ReqToChain = (int *) mem;
4326 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4327 ioc->name, mem, sz));
4328 mem = kmalloc(sz, GFP_ATOMIC);
4332 ioc->RequestNB = (int *) mem;
4333 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4334 ioc->name, mem, sz));
4336 for (ii = 0; ii < ioc->req_depth; ii++) {
4337 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4340 /* ChainToChain size must equal the total number
4341 * of chain buffers to be allocated.
4344 * Calculate the number of chain buffers needed(plus 1) per I/O
4345 * then multiply the maximum number of simultaneous cmds
4347 * num_sge = num sge in request frame + last chain buffer
4348 * scale = num sge per chain buffer if no chain element
4350 scale = ioc->req_sz / ioc->SGE_size;
4351 if (ioc->sg_addr_size == sizeof(u64))
4352 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4354 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4356 if (ioc->sg_addr_size == sizeof(u64)) {
4357 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4358 (ioc->req_sz - 60) / ioc->SGE_size;
4360 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4361 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4363 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4364 ioc->name, num_sge, numSGE));
4366 if (ioc->bus_type == FC) {
4367 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4368 numSGE = MPT_SCSI_FC_SG_DEPTH;
4370 if (numSGE > MPT_SCSI_SG_DEPTH)
4371 numSGE = MPT_SCSI_SG_DEPTH;
4375 while (numSGE - num_sge > 0) {
4377 num_sge += (scale - 1);
4381 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4382 ioc->name, numSGE, num_sge, num_chain));
4384 if (ioc->bus_type == SPI)
4385 num_chain *= MPT_SCSI_CAN_QUEUE;
4387 num_chain *= MPT_FC_CAN_QUEUE;
4389 ioc->num_chain = num_chain;
4391 sz = num_chain * sizeof(int);
4392 if (ioc->ChainToChain == NULL) {
4393 mem = kmalloc(sz, GFP_ATOMIC);
4397 ioc->ChainToChain = (int *) mem;
4398 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4399 ioc->name, mem, sz));
4401 mem = (u8 *) ioc->ChainToChain;
4403 memset(mem, 0xFF, sz);
4407 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4409 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4410 * @ioc: Pointer to MPT_ADAPTER structure
4412 * This routine allocates memory for the MPT reply and request frame
4413 * pools (if necessary), and primes the IOC reply FIFO with
4416 * Returns 0 for success, non-zero for failure.
4419 PrimeIocFifos(MPT_ADAPTER *ioc)
4422 unsigned long flags;
4423 dma_addr_t alloc_dma;
4425 int i, reply_sz, sz, total_size, num_chain;
4430 /* Prime reply FIFO... */
4432 if (ioc->reply_frames == NULL) {
4433 if ( (num_chain = initChainBuffers(ioc)) < 0)
4436 * 1078 errata workaround for the 36GB limitation
4438 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4439 ioc->dma_mask > DMA_BIT_MASK(35)) {
4440 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4441 && !pci_set_consistent_dma_mask(ioc->pcidev,
4442 DMA_BIT_MASK(32))) {
4443 dma_mask = DMA_BIT_MASK(35);
4444 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4445 "setting 35 bit addressing for "
4446 "Request/Reply/Chain and Sense Buffers\n",
4449 /*Reseting DMA mask to 64 bit*/
4450 pci_set_dma_mask(ioc->pcidev,
4452 pci_set_consistent_dma_mask(ioc->pcidev,
4455 printk(MYIOC_s_ERR_FMT
4456 "failed setting 35 bit addressing for "
4457 "Request/Reply/Chain and Sense Buffers\n",
4463 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4464 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4465 ioc->name, ioc->reply_sz, ioc->reply_depth));
4466 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4467 ioc->name, reply_sz, reply_sz));
4469 sz = (ioc->req_sz * ioc->req_depth);
4470 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4471 ioc->name, ioc->req_sz, ioc->req_depth));
4472 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4473 ioc->name, sz, sz));
4476 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4477 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4478 ioc->name, ioc->req_sz, num_chain));
4479 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4480 ioc->name, sz, sz, num_chain));
4483 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4485 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4490 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4491 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4493 memset(mem, 0, total_size);
4494 ioc->alloc_total += total_size;
4496 ioc->alloc_dma = alloc_dma;
4497 ioc->alloc_sz = total_size;
4498 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4499 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4501 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4502 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4504 alloc_dma += reply_sz;
4507 /* Request FIFO - WE manage this! */
4509 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4510 ioc->req_frames_dma = alloc_dma;
4512 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4513 ioc->name, mem, (void *)(ulong)alloc_dma));
4515 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4517 #if defined(CONFIG_MTRR) && 0
4519 * Enable Write Combining MTRR for IOC's memory region.
4520 * (at least as much as we can; "size and base must be
4521 * multiples of 4 kiB"
4523 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4525 MTRR_TYPE_WRCOMB, 1);
4526 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4527 ioc->name, ioc->req_frames_dma, sz));
4530 for (i = 0; i < ioc->req_depth; i++) {
4531 alloc_dma += ioc->req_sz;
4535 ioc->ChainBuffer = mem;
4536 ioc->ChainBufferDMA = alloc_dma;
4538 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4539 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4541 /* Initialize the free chain Q. */
4543 INIT_LIST_HEAD(&ioc->FreeChainQ);
4545 /* Post the chain buffers to the FreeChainQ. */
4546 mem = (u8 *)ioc->ChainBuffer;
4547 for (i=0; i < num_chain; i++) {
4548 mf = (MPT_FRAME_HDR *) mem;
4549 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4553 /* Initialize Request frames linked list
4555 alloc_dma = ioc->req_frames_dma;
4556 mem = (u8 *) ioc->req_frames;
4558 spin_lock_irqsave(&ioc->FreeQlock, flags);
4559 INIT_LIST_HEAD(&ioc->FreeQ);
4560 for (i = 0; i < ioc->req_depth; i++) {
4561 mf = (MPT_FRAME_HDR *) mem;
4563 /* Queue REQUESTs *internally*! */
4564 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4568 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4570 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4571 ioc->sense_buf_pool =
4572 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4573 if (ioc->sense_buf_pool == NULL) {
4574 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4579 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4580 ioc->alloc_total += sz;
4581 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4582 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4586 /* Post Reply frames to FIFO */
4587 alloc_dma = ioc->alloc_dma;
4588 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4589 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4591 for (i = 0; i < ioc->reply_depth; i++) {
4592 /* Write each address to the IOC! */
4593 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4594 alloc_dma += ioc->reply_sz;
4597 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4598 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4600 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4601 "restoring 64 bit addressing\n", ioc->name));
4607 if (ioc->alloc != NULL) {
4609 pci_free_consistent(ioc->pcidev,
4611 ioc->alloc, ioc->alloc_dma);
4612 ioc->reply_frames = NULL;
4613 ioc->req_frames = NULL;
4614 ioc->alloc_total -= sz;
4616 if (ioc->sense_buf_pool != NULL) {
4617 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4618 pci_free_consistent(ioc->pcidev,
4620 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4621 ioc->sense_buf_pool = NULL;
4624 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4625 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4627 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4628 "restoring 64 bit addressing\n", ioc->name));
4633 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4635 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4636 * from IOC via doorbell handshake method.
4637 * @ioc: Pointer to MPT_ADAPTER structure
4638 * @reqBytes: Size of the request in bytes
4639 * @req: Pointer to MPT request frame
4640 * @replyBytes: Expected size of the reply in bytes
4641 * @u16reply: Pointer to area where reply should be written
4642 * @maxwait: Max wait time for a reply (in seconds)
4643 * @sleepFlag: Specifies whether the process can sleep
4645 * NOTES: It is the callers responsibility to byte-swap fields in the
4646 * request which are greater than 1 byte in size. It is also the
4647 * callers responsibility to byte-swap response fields which are
4648 * greater than 1 byte in size.
4650 * Returns 0 for success, non-zero for failure.
4653 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4654 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4656 MPIDefaultReply_t *mptReply;
4661 * Get ready to cache a handshake reply
4663 ioc->hs_reply_idx = 0;
4664 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4665 mptReply->MsgLength = 0;
4668 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4669 * then tell IOC that we want to handshake a request of N words.
4670 * (WRITE u32val to Doorbell reg).
4672 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4673 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4674 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4675 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4678 * Wait for IOC's doorbell handshake int
4680 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4683 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4684 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4686 /* Read doorbell and check for active bit */
4687 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4691 * Clear doorbell int (WRITE 0 to IntStatus reg),
4692 * then wait for IOC to ACKnowledge that it's ready for
4693 * our handshake request.
4695 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4696 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4701 u8 *req_as_bytes = (u8 *) req;
4704 * Stuff request words via doorbell handshake,
4705 * with ACK from IOC for each.
4707 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4708 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4709 (req_as_bytes[(ii*4) + 1] << 8) |
4710 (req_as_bytes[(ii*4) + 2] << 16) |
4711 (req_as_bytes[(ii*4) + 3] << 24));
4713 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4714 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4718 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4719 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4721 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4722 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4725 * Wait for completion of doorbell handshake reply from the IOC
4727 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4730 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4731 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4734 * Copy out the cached reply...
4736 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4737 u16reply[ii] = ioc->hs_reply[ii];
4745 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4747 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4748 * @ioc: Pointer to MPT_ADAPTER structure
4749 * @howlong: How long to wait (in seconds)
4750 * @sleepFlag: Specifies whether the process can sleep
4752 * This routine waits (up to ~2 seconds max) for IOC doorbell
4753 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4754 * bit in its IntStatus register being clear.
4756 * Returns a negative value on failure, else wait loop count.
4759 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4765 cntdn = 1000 * howlong;
4767 if (sleepFlag == CAN_SLEEP) {
4770 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4771 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4778 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4779 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4786 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4791 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4792 ioc->name, count, intstat);
4796 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4798 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4799 * @ioc: Pointer to MPT_ADAPTER structure
4800 * @howlong: How long to wait (in seconds)
4801 * @sleepFlag: Specifies whether the process can sleep
4803 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4804 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4806 * Returns a negative value on failure, else wait loop count.
4809 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4815 cntdn = 1000 * howlong;
4816 if (sleepFlag == CAN_SLEEP) {
4819 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4820 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4827 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4828 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4835 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4836 ioc->name, count, howlong));
4840 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4841 ioc->name, count, intstat);
4845 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4847 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4848 * @ioc: Pointer to MPT_ADAPTER structure
4849 * @howlong: How long to wait (in seconds)
4850 * @sleepFlag: Specifies whether the process can sleep
4852 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4853 * Reply is cached to IOC private area large enough to hold a maximum
4854 * of 128 bytes of reply data.
4856 * Returns a negative value on failure, else size of reply in WORDS.
4859 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4864 u16 *hs_reply = ioc->hs_reply;
4865 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4868 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4871 * Get first two u16's so we can look at IOC's intended reply MsgLength
4874 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4877 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4878 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4879 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4882 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4883 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4887 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4888 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4889 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4892 * If no error (and IOC said MsgLength is > 0), piece together
4893 * reply 16 bits at a time.
4895 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4896 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4898 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4899 /* don't overflow our IOC hs_reply[] buffer! */
4900 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4901 hs_reply[u16cnt] = hword;
4902 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4905 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4907 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4910 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4915 else if (u16cnt != (2 * mptReply->MsgLength)) {
4918 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4923 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4924 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4926 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4927 ioc->name, t, u16cnt/2));
4931 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4933 * GetLanConfigPages - Fetch LANConfig pages.
4934 * @ioc: Pointer to MPT_ADAPTER structure
4936 * Return: 0 for success
4937 * -ENOMEM if no memory available
4938 * -EPERM if not allowed due to ISR context
4939 * -EAGAIN if no msg frames currently available
4940 * -EFAULT for non-successful reply or no reply (timeout)
4943 GetLanConfigPages(MPT_ADAPTER *ioc)
4945 ConfigPageHeader_t hdr;
4947 LANPage0_t *ppage0_alloc;
4948 dma_addr_t page0_dma;
4949 LANPage1_t *ppage1_alloc;
4950 dma_addr_t page1_dma;
4955 /* Get LAN Page 0 header */
4956 hdr.PageVersion = 0;
4959 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4960 cfg.cfghdr.hdr = &hdr;
4962 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4967 if ((rc = mpt_config(ioc, &cfg)) != 0)
4970 if (hdr.PageLength > 0) {
4971 data_sz = hdr.PageLength * 4;
4972 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4975 memset((u8 *)ppage0_alloc, 0, data_sz);
4976 cfg.physAddr = page0_dma;
4977 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4979 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4981 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4982 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4986 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4989 * Normalize endianness of structure data,
4990 * by byte-swapping all > 1 byte fields!
4999 /* Get LAN Page 1 header */
5000 hdr.PageVersion = 0;
5003 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
5004 cfg.cfghdr.hdr = &hdr;
5006 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5010 if ((rc = mpt_config(ioc, &cfg)) != 0)
5013 if (hdr.PageLength == 0)
5016 data_sz = hdr.PageLength * 4;
5018 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
5020 memset((u8 *)ppage1_alloc, 0, data_sz);
5021 cfg.physAddr = page1_dma;
5022 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5024 if ((rc = mpt_config(ioc, &cfg)) == 0) {
5026 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
5027 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
5030 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
5033 * Normalize endianness of structure data,
5034 * by byte-swapping all > 1 byte fields!
5042 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5044 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5045 * @ioc: Pointer to MPT_ADAPTER structure
5046 * @persist_opcode: see below
5048 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5049 * devices not currently present.
5050 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5052 * NOTE: Don't use not this function during interrupt time.
5054 * Returns 0 for success, non-zero error
5057 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5059 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5061 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5062 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5063 MPT_FRAME_HDR *mf = NULL;
5064 MPIHeader_t *mpi_hdr;
5066 unsigned long timeleft;
5068 mutex_lock(&ioc->mptbase_cmds.mutex);
5070 /* init the internal cmd struct */
5071 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5072 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5074 /* insure garbage is not sent to fw */
5075 switch(persist_opcode) {
5077 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5078 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5086 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5087 __func__, persist_opcode);
5089 /* Get a MF for this command.
5091 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5092 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5097 mpi_hdr = (MPIHeader_t *) mf;
5098 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5099 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5100 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5101 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5102 sasIoUnitCntrReq->Operation = persist_opcode;
5104 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5105 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5106 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5108 printk(KERN_DEBUG "%s: failed\n", __func__);
5109 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5112 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
5113 ioc->name, __func__);
5114 if (mpt_SoftResetHandler(ioc, CAN_SLEEP) != 0)
5115 mpt_HardResetHandler(ioc, CAN_SLEEP);
5116 mpt_free_msg_frame(ioc, mf);
5121 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5126 sasIoUnitCntrReply =
5127 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5128 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5129 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5130 __func__, sasIoUnitCntrReply->IOCStatus,
5131 sasIoUnitCntrReply->IOCLogInfo);
5132 printk(KERN_DEBUG "%s: failed\n", __func__);
5135 printk(KERN_DEBUG "%s: success\n", __func__);
5138 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5139 mutex_unlock(&ioc->mptbase_cmds.mutex);
5143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5146 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5147 MpiEventDataRaid_t * pRaidEventData)
5156 volume = pRaidEventData->VolumeID;
5157 reason = pRaidEventData->ReasonCode;
5158 disk = pRaidEventData->PhysDiskNum;
5159 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5160 flags = (status >> 0) & 0xff;
5161 state = (status >> 8) & 0xff;
5163 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5167 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5168 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5169 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5170 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5171 ioc->name, disk, volume);
5173 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5178 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5179 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5183 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5185 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5189 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5190 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5194 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5195 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5197 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5199 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5201 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5204 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5206 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5207 ? ", quiesced" : "",
5208 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5209 ? ", resync in progress" : "" );
5212 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5213 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5217 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5218 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5222 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5223 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5227 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5228 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5232 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5233 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5235 state == MPI_PHYSDISK0_STATUS_ONLINE
5237 : state == MPI_PHYSDISK0_STATUS_MISSING
5239 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5241 : state == MPI_PHYSDISK0_STATUS_FAILED
5243 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5245 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5246 ? "offline requested"
5247 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5248 ? "failed requested"
5249 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5252 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5253 ? ", out of sync" : "",
5254 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5255 ? ", quiesced" : "" );
5258 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5259 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5263 case MPI_EVENT_RAID_RC_SMART_DATA:
5264 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5265 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5268 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5269 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5277 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5278 * @ioc: Pointer to MPT_ADAPTER structure
5280 * Returns: 0 for success
5281 * -ENOMEM if no memory available
5282 * -EPERM if not allowed due to ISR context
5283 * -EAGAIN if no msg frames currently available
5284 * -EFAULT for non-successful reply or no reply (timeout)
5287 GetIoUnitPage2(MPT_ADAPTER *ioc)
5289 ConfigPageHeader_t hdr;
5291 IOUnitPage2_t *ppage_alloc;
5292 dma_addr_t page_dma;
5296 /* Get the page header */
5297 hdr.PageVersion = 0;
5300 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5301 cfg.cfghdr.hdr = &hdr;
5303 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5308 if ((rc = mpt_config(ioc, &cfg)) != 0)
5311 if (hdr.PageLength == 0)
5314 /* Read the config page */
5315 data_sz = hdr.PageLength * 4;
5317 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5319 memset((u8 *)ppage_alloc, 0, data_sz);
5320 cfg.physAddr = page_dma;
5321 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5323 /* If Good, save data */
5324 if ((rc = mpt_config(ioc, &cfg)) == 0)
5325 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5327 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5333 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5335 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5336 * @ioc: Pointer to a Adapter Strucutre
5337 * @portnum: IOC port number
5339 * Return: -EFAULT if read of config page header fails
5341 * If read of SCSI Port Page 0 fails,
5342 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5343 * Adapter settings: async, narrow
5345 * If read of SCSI Port Page 2 fails,
5346 * Adapter settings valid
5347 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5352 * CHECK - what type of locking mechanisms should be used????
5355 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5360 ConfigPageHeader_t header;
5366 if (!ioc->spi_data.nvram) {
5369 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5370 mem = kmalloc(sz, GFP_ATOMIC);
5374 ioc->spi_data.nvram = (int *) mem;
5376 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5377 ioc->name, ioc->spi_data.nvram, sz));
5380 /* Invalidate NVRAM information
5382 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5383 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5386 /* Read SPP0 header, allocate memory, then read page.
5388 header.PageVersion = 0;
5389 header.PageLength = 0;
5390 header.PageNumber = 0;
5391 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5392 cfg.cfghdr.hdr = &header;
5394 cfg.pageAddr = portnum;
5395 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5397 cfg.timeout = 0; /* use default */
5398 if (mpt_config(ioc, &cfg) != 0)
5401 if (header.PageLength > 0) {
5402 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5404 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5405 cfg.physAddr = buf_dma;
5406 if (mpt_config(ioc, &cfg) != 0) {
5407 ioc->spi_data.maxBusWidth = MPT_NARROW;
5408 ioc->spi_data.maxSyncOffset = 0;
5409 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5410 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5412 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5413 "Unable to read PortPage0 minSyncFactor=%x\n",
5414 ioc->name, ioc->spi_data.minSyncFactor));
5416 /* Save the Port Page 0 data
5418 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5419 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5420 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5422 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5423 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5424 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5425 "noQas due to Capabilities=%x\n",
5426 ioc->name, pPP0->Capabilities));
5428 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5429 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5431 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5432 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5433 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5434 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5435 "PortPage0 minSyncFactor=%x\n",
5436 ioc->name, ioc->spi_data.minSyncFactor));
5438 ioc->spi_data.maxSyncOffset = 0;
5439 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5442 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5444 /* Update the minSyncFactor based on bus type.
5446 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5447 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5449 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5450 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5451 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5452 "HVD or SE detected, minSyncFactor=%x\n",
5453 ioc->name, ioc->spi_data.minSyncFactor));
5458 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5463 /* SCSI Port Page 2 - Read the header then the page.
5465 header.PageVersion = 0;
5466 header.PageLength = 0;
5467 header.PageNumber = 2;
5468 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5469 cfg.cfghdr.hdr = &header;
5471 cfg.pageAddr = portnum;
5472 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5474 if (mpt_config(ioc, &cfg) != 0)
5477 if (header.PageLength > 0) {
5478 /* Allocate memory and read SCSI Port Page 2
5480 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5482 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5483 cfg.physAddr = buf_dma;
5484 if (mpt_config(ioc, &cfg) != 0) {
5485 /* Nvram data is left with INVALID mark
5488 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5490 /* This is an ATTO adapter, read Page2 accordingly
5492 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5493 ATTODeviceInfo_t *pdevice = NULL;
5496 /* Save the Port Page 2 data
5497 * (reformat into a 32bit quantity)
5499 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5500 pdevice = &pPP2->DeviceSettings[ii];
5501 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5504 /* Translate ATTO device flags to LSI format
5506 if (ATTOFlags & ATTOFLAG_DISC)
5507 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5508 if (ATTOFlags & ATTOFLAG_ID_ENB)
5509 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5510 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5511 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5512 if (ATTOFlags & ATTOFLAG_TAGGED)
5513 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5514 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5515 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5517 data = (data << 16) | (pdevice->Period << 8) | 10;
5518 ioc->spi_data.nvram[ii] = data;
5521 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5522 MpiDeviceInfo_t *pdevice = NULL;
5525 * Save "Set to Avoid SCSI Bus Resets" flag
5527 ioc->spi_data.bus_reset =
5528 (le32_to_cpu(pPP2->PortFlags) &
5529 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5532 /* Save the Port Page 2 data
5533 * (reformat into a 32bit quantity)
5535 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5536 ioc->spi_data.PortFlags = data;
5537 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5538 pdevice = &pPP2->DeviceSettings[ii];
5539 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5540 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5541 ioc->spi_data.nvram[ii] = data;
5545 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5549 /* Update Adapter limits with those from NVRAM
5550 * Comment: Don't need to do this. Target performance
5551 * parameters will never exceed the adapters limits.
5557 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5559 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5560 * @ioc: Pointer to a Adapter Strucutre
5561 * @portnum: IOC port number
5563 * Return: -EFAULT if read of config page header fails
5567 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5570 ConfigPageHeader_t header;
5572 /* Read the SCSI Device Page 1 header
5574 header.PageVersion = 0;
5575 header.PageLength = 0;
5576 header.PageNumber = 1;
5577 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5578 cfg.cfghdr.hdr = &header;
5580 cfg.pageAddr = portnum;
5581 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5584 if (mpt_config(ioc, &cfg) != 0)
5587 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5588 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5590 header.PageVersion = 0;
5591 header.PageLength = 0;
5592 header.PageNumber = 0;
5593 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5594 if (mpt_config(ioc, &cfg) != 0)
5597 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5598 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5600 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5601 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5603 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5604 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5609 mpt_read_ioc_pg_6(MPT_ADAPTER *ioc)
5612 ConfigPageHeader_t header;
5613 IOCPage6_t *pIoc6=NULL;
5614 dma_addr_t ioc6_dma;
5618 /* Free the old page
5620 if (ioc->raid_data.pIocPg6) {
5621 kfree(ioc->raid_data.pIocPg6);
5622 ioc->raid_data.pIocPg6 = NULL;
5625 /* There is at least one physical disk.
5626 * Read and save IOC Page 3
5628 header.PageVersion = 0;
5629 header.PageLength = 0;
5630 header.PageNumber = 6;
5631 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5632 cfg.cfghdr.hdr = &header;
5635 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5638 if (mpt_config(ioc, &cfg) != 0)
5641 if (header.PageLength == 0)
5644 /* Read Header good, alloc memory
5646 iocpage6sz = header.PageLength * 4;
5647 pIoc6 = pci_alloc_consistent(ioc->pcidev, iocpage6sz, &ioc6_dma);
5651 /* Read the Page and save the data
5652 * into malloc'd memory.
5654 cfg.physAddr = ioc6_dma;
5655 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5656 if (mpt_config(ioc, &cfg) != 0)
5659 mem = kmalloc(iocpage6sz, GFP_ATOMIC);
5663 memcpy(mem, pIoc6, iocpage6sz);
5664 ioc->raid_data.pIocPg6 = mem;
5668 pci_free_consistent(ioc->pcidev, iocpage6sz, pIoc6, ioc6_dma);
5672 * mpt_inactive_raid_list_free - This clears this link list.
5673 * @ioc : pointer to per adapter structure
5676 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5678 struct inactive_raid_component_info *component_info, *pNext;
5680 if (list_empty(&ioc->raid_data.inactive_list))
5683 down(&ioc->raid_data.inactive_list_mutex);
5684 list_for_each_entry_safe(component_info, pNext,
5685 &ioc->raid_data.inactive_list, list) {
5686 list_del(&component_info->list);
5687 kfree(component_info);
5689 up(&ioc->raid_data.inactive_list_mutex);
5693 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5695 * @ioc : pointer to per adapter structure
5696 * @channel : volume channel
5697 * @id : volume target id
5700 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5703 ConfigPageHeader_t hdr;
5704 dma_addr_t dma_handle;
5705 pRaidVolumePage0_t buffer = NULL;
5707 RaidPhysDiskPage0_t phys_disk;
5708 RaidPhysDiskPage1_t *phys_disk_1;
5709 struct inactive_raid_component_info *component_info;
5710 int handle_inactive_volumes;
5711 int num_paths, device_is_online;
5713 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5714 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5715 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5716 cfg.pageAddr = (channel << 8) + id;
5717 cfg.cfghdr.hdr = &hdr;
5718 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5720 if (mpt_config(ioc, &cfg) != 0)
5723 if (!hdr.PageLength)
5726 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5732 cfg.physAddr = dma_handle;
5733 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5735 if (mpt_config(ioc, &cfg) != 0)
5738 if (!buffer->NumPhysDisks)
5741 handle_inactive_volumes =
5742 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5743 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5744 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5745 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5747 if (!handle_inactive_volumes)
5750 down(&ioc->raid_data.inactive_list_mutex);
5751 for (i = 0; i < buffer->NumPhysDisks; i++) {
5752 if(mpt_raid_phys_disk_pg0(ioc,
5753 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5756 if (phys_disk.PhysDiskStatus.State !=
5757 MPI_PHYSDISK0_STATUS_ONLINE)
5760 /* check to see if device is online by checking phys_disk_pg1 */
5761 device_is_online = 0;
5762 num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
5763 buffer->PhysDisk[i].PhysDiskNum);
5766 phys_disk_1 = kzalloc(offsetof(RaidPhysDiskPage1_t,Path) +
5767 (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
5770 mpt_raid_phys_disk_pg1(ioc, buffer->PhysDisk[i].PhysDiskNum,
5772 for (j = 0; j < num_paths && !device_is_online; j++)
5773 if (!phys_disk_1->Path[j].Flags)
5774 device_is_online = 1;
5776 if (!device_is_online)
5779 if ((component_info = kmalloc(sizeof (*component_info),
5780 GFP_KERNEL)) == NULL)
5783 component_info->volumeID = id;
5784 component_info->volumeBus = channel;
5785 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5786 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5787 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5788 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5790 list_add_tail(&component_info->list,
5791 &ioc->raid_data.inactive_list);
5793 up(&ioc->raid_data.inactive_list_mutex);
5797 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5802 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5803 * @ioc: Pointer to a Adapter Structure
5804 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5805 * @phys_disk: requested payload data returned
5809 * -EFAULT if read of config page header fails or data pointer not NULL
5810 * -ENOMEM if pci_alloc failed
5813 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5814 RaidPhysDiskPage0_t *phys_disk)
5817 ConfigPageHeader_t hdr;
5818 dma_addr_t dma_handle;
5819 pRaidPhysDiskPage0_t buffer = NULL;
5822 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5823 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5824 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5826 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5827 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5828 cfg.cfghdr.hdr = &hdr;
5830 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5832 if (mpt_config(ioc, &cfg) != 0) {
5837 if (!hdr.PageLength) {
5842 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5850 cfg.physAddr = dma_handle;
5851 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5852 cfg.pageAddr = phys_disk_num;
5854 if (mpt_config(ioc, &cfg) != 0) {
5860 memcpy(phys_disk, buffer, sizeof(*buffer));
5861 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5866 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5873 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5874 * @ioc: Pointer to a Adapter Structure
5875 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5878 * returns number paths
5881 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5884 ConfigPageHeader_t hdr;
5885 dma_addr_t dma_handle;
5886 pRaidPhysDiskPage1_t buffer = NULL;
5889 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5890 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5892 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5893 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5895 cfg.cfghdr.hdr = &hdr;
5897 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5899 if (mpt_config(ioc, &cfg) != 0) {
5904 if (!hdr.PageLength) {
5909 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5917 cfg.physAddr = dma_handle;
5918 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5919 cfg.pageAddr = phys_disk_num;
5921 if (mpt_config(ioc, &cfg) != 0) {
5926 rc = buffer->NumPhysDiskPaths;
5930 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5937 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5938 * @ioc: Pointer to a Adapter Structure
5939 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5940 * @phys_disk: requested payload data returned
5944 * -EFAULT if read of config page header fails or data pointer not NULL
5945 * -ENOMEM if pci_alloc failed
5948 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num, RaidPhysDiskPage1_t *phys_disk)
5951 ConfigPageHeader_t hdr;
5952 dma_addr_t dma_handle;
5953 pRaidPhysDiskPage1_t buffer = NULL;
5958 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5959 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5962 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5963 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5965 cfg.cfghdr.hdr = &hdr;
5967 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5969 if (mpt_config(ioc, &cfg) != 0) {
5974 if (!hdr.PageLength) {
5979 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5987 cfg.physAddr = dma_handle;
5988 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5989 cfg.pageAddr = phys_disk_num;
5991 if (mpt_config(ioc, &cfg) != 0) {
5996 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5997 phys_disk->PhysDiskNum = phys_disk_num;
5998 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5999 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
6000 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
6001 phys_disk->Path[i].OwnerIdentifier = buffer->Path[i].OwnerIdentifier;
6002 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
6003 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
6004 sas_address = le64_to_cpu(sas_address);
6005 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
6006 memcpy(&sas_address, &buffer->Path[i].OwnerWWID, sizeof(__le64));
6007 sas_address = le64_to_cpu(sas_address);
6008 memcpy(&phys_disk->Path[i].OwnerWWID, &sas_address, sizeof(__le64));
6014 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
6021 * mpt_sort_ioc_pg2 - compare function for sorting volumes
6022 * in ascending order
6023 * @a: ioc_pg2 raid volume page
6024 * @b: ioc_pg2 raid volume page
6027 * 0 same, 1 (a is bigger), -1 (b is bigger)
6030 mpt_sort_ioc_pg2(const void *a, const void *b)
6032 ConfigPageIoc2RaidVol_t * volume_a = (ConfigPageIoc2RaidVol_t *)a;
6033 ConfigPageIoc2RaidVol_t * volume_b = (ConfigPageIoc2RaidVol_t *)b;
6035 if (volume_a->VolumeBus == volume_b->VolumeBus) {
6036 if (volume_a->VolumeID == volume_b->VolumeID)
6038 if (volume_a->VolumeID < volume_b->VolumeID)
6042 if (volume_a->VolumeBus < volume_b->VolumeBus)
6048 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
6049 * @ioc: Pointer to a Adapter Strucutre
6053 * -EFAULT if read of config page header fails or data pointer not NULL
6054 * -ENOMEM if pci_alloc failed
6057 mpt_findImVolumes(MPT_ADAPTER *ioc)
6061 dma_addr_t ioc2_dma;
6063 ConfigPageHeader_t header;
6068 if (!ioc->ir_firmware)
6071 /* Free the old page
6073 kfree(ioc->raid_data.pIocPg2);
6074 ioc->raid_data.pIocPg2 = NULL;
6075 mpt_inactive_raid_list_free(ioc);
6077 /* Read IOCP2 header then the page.
6079 header.PageVersion = 0;
6080 header.PageLength = 0;
6081 header.PageNumber = 2;
6082 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6083 cfg.cfghdr.hdr = &header;
6086 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6089 if (mpt_config(ioc, &cfg) != 0)
6092 if (header.PageLength == 0)
6095 iocpage2sz = header.PageLength * 4;
6096 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
6100 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6101 cfg.physAddr = ioc2_dma;
6102 if (mpt_config(ioc, &cfg) != 0)
6105 mem = kmalloc(iocpage2sz, GFP_KERNEL);
6110 * sort volumes in ascending order
6112 sort(pIoc2->RaidVolume, pIoc2->NumActiveVolumes,
6113 sizeof(ConfigPageIoc2RaidVol_t), mpt_sort_ioc_pg2, NULL);
6114 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
6115 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
6117 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
6118 mpt_inactive_raid_volumes(ioc,
6119 pIoc2->RaidVolume[i].VolumeBus,
6120 pIoc2->RaidVolume[i].VolumeID);
6122 mpt_read_ioc_pg_3(ioc);
6123 mpt_read_ioc_pg_6(ioc);
6126 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
6132 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
6137 ConfigPageHeader_t header;
6138 dma_addr_t ioc3_dma;
6141 /* Free the old page
6143 kfree(ioc->raid_data.pIocPg3);
6144 ioc->raid_data.pIocPg3 = NULL;
6146 /* There is at least one physical disk.
6147 * Read and save IOC Page 3
6149 header.PageVersion = 0;
6150 header.PageLength = 0;
6151 header.PageNumber = 3;
6152 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6153 cfg.cfghdr.hdr = &header;
6156 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6159 if (mpt_config(ioc, &cfg) != 0)
6162 if (header.PageLength == 0)
6165 /* Read Header good, alloc memory
6167 iocpage3sz = header.PageLength * 4;
6168 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6172 /* Read the Page and save the data
6173 * into malloc'd memory.
6175 cfg.physAddr = ioc3_dma;
6176 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6177 if (mpt_config(ioc, &cfg) == 0) {
6178 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6180 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6181 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6185 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6191 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6195 ConfigPageHeader_t header;
6196 dma_addr_t ioc4_dma;
6199 /* Read and save IOC Page 4
6201 header.PageVersion = 0;
6202 header.PageLength = 0;
6203 header.PageNumber = 4;
6204 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6205 cfg.cfghdr.hdr = &header;
6208 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6211 if (mpt_config(ioc, &cfg) != 0)
6214 if (header.PageLength == 0)
6217 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6218 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6219 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6222 ioc->alloc_total += iocpage4sz;
6224 ioc4_dma = ioc->spi_data.IocPg4_dma;
6225 iocpage4sz = ioc->spi_data.IocPg4Sz;
6228 /* Read the Page into dma memory.
6230 cfg.physAddr = ioc4_dma;
6231 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6232 if (mpt_config(ioc, &cfg) == 0) {
6233 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6234 ioc->spi_data.IocPg4_dma = ioc4_dma;
6235 ioc->spi_data.IocPg4Sz = iocpage4sz;
6237 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6238 ioc->spi_data.pIocPg4 = NULL;
6239 ioc->alloc_total -= iocpage4sz;
6244 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6248 ConfigPageHeader_t header;
6249 dma_addr_t ioc1_dma;
6253 /* Check the Coalescing Timeout in IOC Page 1
6255 header.PageVersion = 0;
6256 header.PageLength = 0;
6257 header.PageNumber = 1;
6258 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6259 cfg.cfghdr.hdr = &header;
6262 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6265 if (mpt_config(ioc, &cfg) != 0)
6268 if (header.PageLength == 0)
6271 /* Read Header good, alloc memory
6273 iocpage1sz = header.PageLength * 4;
6274 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6278 /* Read the Page and check coalescing timeout
6280 cfg.physAddr = ioc1_dma;
6281 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6282 if (mpt_config(ioc, &cfg) == 0) {
6284 #if defined(CPQ_CIM)
6285 ioc->pci_slot_number = pIoc1->PCISlotNum;
6287 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6288 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6289 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6291 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6294 if (tmp > MPT_COALESCING_TIMEOUT) {
6295 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6297 /* Write NVRAM and current
6300 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6301 if (mpt_config(ioc, &cfg) == 0) {
6302 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6303 ioc->name, MPT_COALESCING_TIMEOUT));
6305 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6306 if (mpt_config(ioc, &cfg) == 0) {
6307 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6308 "Reset NVRAM Coalescing Timeout to = %d\n",
6309 ioc->name, MPT_COALESCING_TIMEOUT));
6311 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6312 "Reset NVRAM Coalescing Timeout Failed\n",
6317 dprintk(ioc, printk(MYIOC_s_WARN_FMT
6318 "Reset of Current Coalescing Timeout Failed!\n",
6324 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6328 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6334 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6337 ConfigPageHeader_t hdr;
6339 ManufacturingPage0_t *pbuf = NULL;
6341 memset(&cfg, 0 , sizeof(CONFIGPARMS));
6342 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6344 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6345 cfg.cfghdr.hdr = &hdr;
6347 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6350 if (mpt_config(ioc, &cfg) != 0)
6353 if (!cfg.cfghdr.hdr->PageLength)
6356 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6357 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6361 cfg.physAddr = buf_dma;
6363 if (mpt_config(ioc, &cfg) != 0)
6366 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6367 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6368 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6373 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6376 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6378 * SendEventNotification - Send EventNotification (on or off) request to adapter
6379 * @ioc: Pointer to MPT_ADAPTER structure
6380 * @EvSwitch: Event switch flags
6381 * @sleepFlag: Specifies whether the process can sleep
6384 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6386 EventNotification_t evn;
6387 MPIDefaultReply_t reply_buf;
6389 memset(&evn, 0, sizeof(EventNotification_t));
6390 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6392 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6393 evn.Switch = EvSwitch;
6394 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6396 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6397 "Sending EventNotification (%d) request %p\n",
6398 ioc->name, EvSwitch, &evn));
6400 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6401 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6405 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6407 * SendEventAck - Send EventAck request to MPT adapter.
6408 * @ioc: Pointer to MPT_ADAPTER structure
6409 * @evnp: Pointer to original EventNotification request
6412 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6416 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6417 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6418 ioc->name, __func__));
6422 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6424 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6425 pAck->ChainOffset = 0;
6426 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6428 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6429 pAck->Event = evnp->Event;
6430 pAck->EventContext = evnp->EventContext;
6432 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6437 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6439 * mpt_config - Generic function to issue config message
6440 * @ioc: Pointer to an adapter structure
6441 * @pCfg: Pointer to a configuration structure. Struct contains
6442 * action, page address, direction, physical address
6443 * and pointer to a configuration page header
6444 * Page header is updated.
6446 * Returns 0 for success
6447 * -EPERM if not allowed due to ISR context
6448 * -EAGAIN if no msg frames currently available
6449 * -EFAULT for non-successful reply or no reply (timeout)
6452 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6455 ConfigReply_t *pReply;
6456 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6462 u8 page_type = 0, extend_page;
6463 unsigned long timeleft;
6464 unsigned long flags;
6466 u8 issue_hard_reset = 0;
6469 /* Prevent calling wait_event() (below), if caller happens
6470 * to be in ISR context, because that is fatal!
6472 in_isr = in_interrupt();
6474 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6479 /* don't send a config page during diag reset */
6480 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6481 if (ioc->ioc_reset_in_progress) {
6482 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6483 "%s: busy with host reset\n", ioc->name, __func__));
6484 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6487 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6489 /* don't send if no chance of success */
6491 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6492 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6493 "%s: ioc not operational, %d, %xh\n",
6494 ioc->name, __func__, ioc->active,
6495 mpt_GetIocState(ioc, 0)));
6500 mutex_lock(&ioc->mptbase_cmds.mutex);
6501 /* init the internal cmd struct */
6502 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6503 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6505 /* Get and Populate a free Frame
6507 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6508 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6509 "mpt_config: no msg frames!\n", ioc->name));
6514 pReq = (Config_t *)mf;
6515 pReq->Action = pCfg->action;
6517 pReq->ChainOffset = 0;
6518 pReq->Function = MPI_FUNCTION_CONFIG;
6520 /* Assume page type is not extended and clear "reserved" fields. */
6521 pReq->ExtPageLength = 0;
6522 pReq->ExtPageType = 0;
6525 for (ii=0; ii < 8; ii++)
6526 pReq->Reserved2[ii] = 0;
6528 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6529 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6530 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6531 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6533 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6534 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6535 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6536 pReq->ExtPageType = pExtHdr->ExtPageType;
6537 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6539 /* Page Length must be treated as a reserved field for the
6542 pReq->Header.PageLength = 0;
6545 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6547 /* Add a SGE to the config request.
6550 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6552 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6554 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6555 MPI_CONFIG_PAGETYPE_EXTENDED) {
6556 flagsLength |= pExtHdr->ExtPageLength * 4;
6557 page_type = pReq->ExtPageType;
6560 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6561 page_type = pReq->Header.PageType;
6565 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6566 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6567 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6569 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6570 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6571 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6572 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6574 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6576 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6577 "Failed Sending Config request type 0x%x, page 0x%x,"
6578 " action %d, status %xh, time left %ld\n\n",
6579 ioc->name, page_type, pReq->Header.PageNumber,
6580 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6581 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6584 issue_hard_reset = 1;
6588 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6592 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6593 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6594 if (ret == MPI_IOCSTATUS_SUCCESS) {
6596 pCfg->cfghdr.ehdr->ExtPageLength =
6597 le16_to_cpu(pReply->ExtPageLength);
6598 pCfg->cfghdr.ehdr->ExtPageType =
6599 pReply->ExtPageType;
6601 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6602 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6603 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6604 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6609 printk(MYIOC_s_INFO_FMT "Retry completed "
6610 "ret=0x%x timeleft=%ld\n",
6611 ioc->name, ret, timeleft);
6613 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6614 ret, le32_to_cpu(pReply->IOCLogInfo)));
6618 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6619 mutex_unlock(&ioc->mptbase_cmds.mutex);
6620 if (issue_hard_reset) {
6621 issue_hard_reset = 0;
6622 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
6623 ioc->name, __func__);
6624 if (mpt_SoftResetHandler(ioc, CAN_SLEEP) != 0)
6625 mpt_HardResetHandler(ioc, CAN_SLEEP);
6626 mpt_free_msg_frame(ioc, mf);
6627 /* attempt one retry for a timed out command */
6629 printk(MYIOC_s_INFO_FMT
6630 "Attempting Retry Config request"
6631 " type 0x%x, page 0x%x,"
6632 " action %d\n", ioc->name, page_type,
6633 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6641 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6643 * mpt_ioc_reset - Base cleanup for hard reset
6644 * @ioc: Pointer to the adapter structure
6645 * @reset_phase: Indicates pre- or post-reset functionality
6647 * Remark: Frees resources with internally generated commands.
6650 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6652 switch (reset_phase) {
6653 case MPT_IOC_SETUP_RESET:
6654 ioc->taskmgmt_quiesce_io = 1;
6655 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6656 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6658 case MPT_IOC_PRE_RESET:
6659 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6660 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6662 case MPT_IOC_POST_RESET:
6663 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6664 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6665 /* wake up mptbase_cmds */
6666 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6667 ioc->mptbase_cmds.status |=
6668 MPT_MGMT_STATUS_DID_IOCRESET;
6669 complete(&ioc->mptbase_cmds.done);
6671 /* wake up taskmgmt_cmds */
6672 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6673 ioc->taskmgmt_cmds.status |=
6674 MPT_MGMT_STATUS_DID_IOCRESET;
6675 complete(&ioc->taskmgmt_cmds.done);
6682 return 1; /* currently means nothing really */
6686 #ifdef CONFIG_PROC_FS /* { */
6687 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6689 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6691 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6693 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6695 * Returns 0 for success, non-zero for failure.
6698 procmpt_create(void)
6700 struct proc_dir_entry *ent;
6702 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6703 if (mpt_proc_root_dir == NULL)
6706 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6708 ent->read_proc = procmpt_summary_read;
6710 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6712 ent->read_proc = procmpt_version_read;
6717 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6719 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6721 * Returns 0 for success, non-zero for failure.
6724 procmpt_destroy(void)
6726 remove_proc_entry("version", mpt_proc_root_dir);
6727 remove_proc_entry("summary", mpt_proc_root_dir);
6728 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6731 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6733 * procmpt_summary_read - Handle read request of a summary file
6734 * @buf: Pointer to area to write information
6735 * @start: Pointer to start pointer
6736 * @offset: Offset to start writing
6737 * @request: Amount of read data requested
6738 * @eof: Pointer to EOF integer
6741 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6742 * Returns number of characters written to process performing the read.
6745 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6755 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6759 list_for_each_entry(ioc, &ioc_list, list) {
6762 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6765 if ((out-buf) >= request)
6772 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6775 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6777 * procmpt_version_read - Handle read request from /proc/mpt/version.
6778 * @buf: Pointer to area to write information
6779 * @start: Pointer to start pointer
6780 * @offset: Offset to start writing
6781 * @request: Amount of read data requested
6782 * @eof: Pointer to EOF integer
6785 * Returns number of characters written to process performing the read.
6788 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6791 int scsi, fc, sas, lan, ctl, targ, dmp;
6795 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6796 len += sprintf(buf+len, " Fusion MPT base driver\n");
6798 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6799 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6801 if (MptCallbacks[cb_idx]) {
6802 switch (MptDriverClass[cb_idx]) {
6804 if (!scsi++) drvname = "SPI host";
6807 if (!fc++) drvname = "FC host";
6810 if (!sas++) drvname = "SAS host";
6813 if (!lan++) drvname = "LAN";
6816 if (!targ++) drvname = "SCSI target";
6819 if (!ctl++) drvname = "ioctl";
6824 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6828 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6831 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6833 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6834 * @buf: Pointer to area to write information
6835 * @start: Pointer to start pointer
6836 * @offset: Offset to start writing
6837 * @request: Amount of read data requested
6838 * @eof: Pointer to EOF integer
6841 * Returns number of characters written to process performing the read.
6844 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6846 MPT_ADAPTER *ioc = data;
6852 mpt_get_fw_exp_ver(expVer, ioc);
6854 len = sprintf(buf, "%s:", ioc->name);
6855 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6856 len += sprintf(buf+len, " (f/w download boot flag set)");
6857 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6858 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6860 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6861 ioc->facts.ProductID,
6863 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6864 if (ioc->facts.FWImageSize)
6865 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6866 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6867 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6868 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6870 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6871 ioc->facts.CurrentHostMfaHighAddr);
6872 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6873 ioc->facts.CurrentSenseBufferHighAddr);
6875 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6876 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6878 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6879 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6881 * Rounding UP to nearest 4-kB boundary here...
6883 sz = (ioc->req_sz * ioc->req_depth) + 128;
6884 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6885 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6886 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6887 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6888 4*ioc->facts.RequestFrameSize,
6889 ioc->facts.GlobalCredits);
6891 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6892 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6893 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6894 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6895 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6896 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6897 ioc->facts.CurReplyFrameSize,
6898 ioc->facts.ReplyQueueDepth);
6900 len += sprintf(buf+len, " MaxDevices = %d\n",
6901 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6902 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6905 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6906 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6908 ioc->facts.NumberOfPorts);
6909 if (ioc->bus_type == FC) {
6910 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6911 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6912 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6913 a[5], a[4], a[3], a[2], a[1], a[0]);
6915 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6916 ioc->fc_port_page0[p].WWNN.High,
6917 ioc->fc_port_page0[p].WWNN.Low,
6918 ioc->fc_port_page0[p].WWPN.High,
6919 ioc->fc_port_page0[p].WWPN.Low);
6923 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6926 #endif /* CONFIG_PROC_FS } */
6928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6930 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6933 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6934 sprintf(buf, " (Exp %02d%02d)",
6935 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6936 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6939 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6940 strcat(buf, " [MDBG]");
6944 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6946 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6947 * @ioc: Pointer to MPT_ADAPTER structure
6948 * @buffer: Pointer to buffer where IOC summary info should be written
6949 * @size: Pointer to number of bytes we wrote (set by this routine)
6950 * @len: Offset at which to start writing in buffer
6951 * @showlan: Display LAN stuff?
6953 * This routine writes (english readable) ASCII text, which represents
6954 * a summary of IOC information, to a buffer.
6957 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6962 mpt_get_fw_exp_ver(expVer, ioc);
6965 * Shorter summary of attached ioc's...
6967 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6970 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6971 ioc->facts.FWVersion.Word,
6973 ioc->facts.NumberOfPorts,
6976 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6977 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6978 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6979 a[5], a[4], a[3], a[2], a[1], a[0]);
6982 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6985 y += sprintf(buffer+len+y, " (disabled)");
6987 y += sprintf(buffer+len+y, "\n");
6992 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task managment
6993 * @ioc: Pointer to MPT_ADAPTER structure
6995 * Returns 0 for SUCCESS or -1 if FAILED.
6997 * If -1 is return, then it was not possible to set the flags
7000 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
7002 unsigned long flags;
7005 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7006 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
7007 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
7009 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7013 ioc->taskmgmt_in_progress = 1;
7014 ioc->taskmgmt_quiesce_io = 1;
7016 ioc->alt_ioc->taskmgmt_in_progress = 1;
7017 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
7019 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7026 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task managment
7027 * @ioc: Pointer to MPT_ADAPTER structure
7031 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
7033 unsigned long flags;
7035 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7036 ioc->taskmgmt_in_progress = 0;
7037 ioc->taskmgmt_quiesce_io = 0;
7039 ioc->alt_ioc->taskmgmt_in_progress = 0;
7040 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7042 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7046 * mpt_halt_firmware - Halts the firmware if it is operational and panic
7048 * @ioc: Pointer to MPT_ADAPTER structure
7052 mpt_halt_firmware(MPT_ADAPTER *ioc)
7056 ioc_raw_state = mpt_GetIocState(ioc, 0);
7058 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
7059 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
7060 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
7061 if(mpt_fwfault_debug == 2)
7064 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
7065 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
7067 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
7068 if(mpt_fwfault_debug == 2) {
7069 printk("%s: Firmware is halted due to command timeout\n"
7074 panic("%s: Firmware is halted due to command timeout\n",
7080 * mpt_SoftResetHandler - Issues a less expensive reset
7081 * @ioc: Pointer to MPT_ADAPTER structure
7082 * @sleepFlag: Indicates if sleep or schedule must be called.
7085 * Returns 0 for SUCCESS or -1 if FAILED.
7087 * Message Unit Reset - instructs the IOC to reset the Reply Post and
7088 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
7089 * All posted buffers are freed, and event notification is turned off.
7090 * IOC doesnt reply to any outstanding request. This will transfer IOC
7094 mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7099 unsigned long flags;
7101 unsigned long time_count;
7104 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n", ioc->name));
7106 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7108 if(mpt_fwfault_debug)
7109 mpt_halt_firmware(ioc);
7111 if (ioc_state == MPI_IOC_STATE_FAULT || ioc_state == MPI_IOC_STATE_RESET) {
7112 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7113 "skipping, either in FAULT or RESET state!\n", ioc->name));
7117 if (ioc->bus_type == FC) {
7118 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7119 "skipping, because the bus type is FC!\n", ioc->name));
7123 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7124 if (ioc->ioc_reset_in_progress) {
7125 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7128 ioc->ioc_reset_in_progress = 1;
7129 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7133 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7134 if (MptResetHandlers[cb_idx])
7135 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7138 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7139 if (ioc->taskmgmt_in_progress) {
7140 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7143 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7144 /* Disable reply interrupts (also blocks FreeQ) */
7145 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
7147 time_count = jiffies;
7149 rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
7151 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7152 if (MptResetHandlers[cb_idx])
7153 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
7159 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7160 if (ioc_state != MPI_IOC_STATE_READY)
7163 for (ii = 0; ii < 5; ii++) {
7164 /* Get IOC facts! Allow 5 retries */
7165 if ((rc = GetIocFacts(ioc, sleepFlag,
7166 MPT_HOSTEVENT_IOC_RECOVER)) == 0)
7168 if (sleepFlag == CAN_SLEEP) {
7177 if ((rc = PrimeIocFifos(ioc)) != 0)
7180 if ((rc = SendIocInit(ioc, sleepFlag)) != 0)
7183 if ((rc = SendEventNotification(ioc, 1, sleepFlag)) != 0)
7186 if (ioc->hard_resets < -1)
7190 * At this point, we know soft reset succeeded.
7194 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7197 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7198 ioc->ioc_reset_in_progress = 0;
7199 ioc->taskmgmt_quiesce_io = 0;
7200 ioc->taskmgmt_in_progress = 0;
7201 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7203 if (ioc->active) { /* otherwise, hard reset coming */
7204 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7205 if (MptResetHandlers[cb_idx])
7206 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7210 * Cleanup diag buffer allocated memory
7212 for (i = 0; i < MPI_DIAG_BUF_TYPE_COUNT; i++) {
7213 if (ioc->DiagBuffer[i] == NULL)
7215 pci_free_consistent(ioc->pcidev, ioc->DiagBuffer_sz[i],
7216 ioc->DiagBuffer[i], ioc->DiagBuffer_dma[i]);
7217 ioc->DiagBuffer[i] = NULL;
7218 ioc->DiagBuffer_Status[i] = 0;
7221 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler: completed (%d seconds): %s\n",
7222 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7223 ((rc == 0) ? "SUCCESS" : "FAILED")));
7228 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7230 * mpt_HardResetHandler - Generic reset handler
7231 * @ioc: Pointer to MPT_ADAPTER structure
7232 * @sleepFlag: Indicates if sleep or schedule must be called.
7234 * Issues SCSI Task Management call based on input arg values.
7235 * If TaskMgmt fails, returns associated SCSI request.
7237 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7238 * or a non-interrupt thread. In the former, must not call schedule().
7240 * Note: A return of -1 is a FATAL error case, as it means a
7241 * FW reload/initialization failed.
7243 * Returns 0 for SUCCESS or -1 if FAILED.
7246 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7250 unsigned long flags;
7251 unsigned long time_count;
7253 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7255 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7256 printk("MF count 0x%x !\n", ioc->mfcnt);
7258 if (mpt_fwfault_debug)
7259 mpt_halt_firmware(ioc);
7261 /* Reset the adapter. Prevent more than 1 call to
7262 * mpt_do_ioc_recovery at any instant in time.
7264 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7265 if (ioc->ioc_reset_in_progress) {
7266 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7269 ioc->ioc_reset_in_progress = 1;
7271 ioc->alt_ioc->ioc_reset_in_progress = 1;
7272 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7275 /* The SCSI driver needs to adjust timeouts on all current
7276 * commands prior to the diagnostic reset being issued.
7277 * Prevents timeouts occurring during a diagnostic reset...very bad.
7278 * For all other protocol drivers, this is a no-op.
7280 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7281 if (MptResetHandlers[cb_idx]) {
7282 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7284 mpt_signal_reset(cb_idx, ioc->alt_ioc,
7285 MPT_IOC_SETUP_RESET);
7289 time_count = jiffies;
7290 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
7291 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
7294 if (ioc->hard_resets < -1)
7298 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7299 if (ioc->is_fault == 1)
7301 ioc->taskmgmt_quiesce_io = 0;
7302 ioc->ioc_reset_in_progress = 0;
7303 ioc->taskmgmt_in_progress = 0;
7305 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7306 ioc->alt_ioc->ioc_reset_in_progress = 0;
7307 ioc->alt_ioc->taskmgmt_in_progress = 0;
7309 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7311 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7312 if (MptResetHandlers[cb_idx]) {
7313 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7315 mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
7320 * Cleanup diag buffer allocated memory
7322 for (i = 0; i < MPI_DIAG_BUF_TYPE_COUNT; i++) {
7323 if (ioc->DiagBuffer[i] == NULL)
7325 pci_free_consistent(ioc->pcidev, ioc->DiagBuffer_sz[i],
7326 ioc->DiagBuffer[i], ioc->DiagBuffer_dma[i]);
7327 ioc->DiagBuffer[i] = NULL;
7328 ioc->DiagBuffer_Status[i] = 0;
7332 printk(MYIOC_s_DEBUG_FMT
7333 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7334 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7335 "SUCCESS" : "FAILED")));
7340 #ifdef CONFIG_FUSION_LOGGING
7342 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7348 char *evStr = ioc->evStr;
7350 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7351 evData0 = le32_to_cpu(pEventReply->Data[0]);
7354 case MPI_EVENT_NONE:
7357 case MPI_EVENT_LOG_DATA:
7360 case MPI_EVENT_STATE_CHANGE:
7361 ds = "State Change";
7363 case MPI_EVENT_UNIT_ATTENTION:
7364 ds = "Unit Attention";
7366 case MPI_EVENT_IOC_BUS_RESET:
7367 ds = "IOC Bus Reset";
7369 case MPI_EVENT_EXT_BUS_RESET:
7370 ds = "External Bus Reset";
7372 case MPI_EVENT_RESCAN:
7373 ds = "Bus Rescan Event";
7375 case MPI_EVENT_LINK_STATUS_CHANGE:
7376 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7377 ds = "Link Status(FAILURE) Change";
7379 ds = "Link Status(ACTIVE) Change";
7381 case MPI_EVENT_LOOP_STATE_CHANGE:
7382 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7383 ds = "Loop State(LIP) Change";
7384 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7385 ds = "Loop State(LPE) Change";
7387 ds = "Loop State(LPB) Change";
7389 case MPI_EVENT_LOGOUT:
7392 case MPI_EVENT_EVENT_CHANGE:
7398 case MPI_EVENT_INTEGRATED_RAID:
7400 u8 ReasonCode = (u8)(evData0 >> 16);
7401 switch (ReasonCode) {
7402 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7403 ds = "Integrated Raid: Volume Created";
7405 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7406 ds = "Integrated Raid: Volume Deleted";
7408 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7409 ds = "Integrated Raid: Volume Settings Changed";
7411 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7412 ds = "Integrated Raid: Volume Status Changed";
7414 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7415 ds = "Integrated Raid: Volume Physdisk Changed";
7417 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7418 ds = "Integrated Raid: Physdisk Created";
7420 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7421 ds = "Integrated Raid: Physdisk Deleted";
7423 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7424 ds = "Integrated Raid: Physdisk Settings Changed";
7426 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7427 ds = "Integrated Raid: Physdisk Status Changed";
7429 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7430 ds = "Integrated Raid: Domain Validation Needed";
7432 case MPI_EVENT_RAID_RC_SMART_DATA :
7433 ds = "Integrated Raid; Smart Data";
7435 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7436 ds = "Integrated Raid: Replace Action Started";
7439 ds = "Integrated Raid";
7444 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7445 ds = "SCSI Device Status Change";
7447 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7449 u8 id = (u8)(evData0);
7450 u8 channel = (u8)(evData0 >> 8);
7451 u8 ReasonCode = (u8)(evData0 >> 16);
7452 switch (ReasonCode) {
7453 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7454 snprintf(evStr, EVENT_DESCR_STR_SZ,
7455 "SAS Device Status Change: Added: "
7456 "id=%d channel=%d", id, channel);
7458 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7459 snprintf(evStr, EVENT_DESCR_STR_SZ,
7460 "SAS Device Status Change: Deleted: "
7461 "id=%d channel=%d", id, channel);
7463 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7464 snprintf(evStr, EVENT_DESCR_STR_SZ,
7465 "SAS Device Status Change: SMART Data: "
7466 "id=%d channel=%d", id, channel);
7468 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7469 snprintf(evStr, EVENT_DESCR_STR_SZ,
7470 "SAS Device Status Change: No Persistancy: "
7471 "id=%d channel=%d", id, channel);
7473 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7474 snprintf(evStr, EVENT_DESCR_STR_SZ,
7475 "SAS Device Status Change: Unsupported Device "
7476 "Discovered : id=%d channel=%d", id, channel);
7478 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7479 snprintf(evStr, EVENT_DESCR_STR_SZ,
7480 "SAS Device Status Change: Internal Device "
7481 "Reset : id=%d channel=%d", id, channel);
7483 case MPI_EVENT_SAS_DEV_STAT_RC_CMPL_INTERNAL_DEV_RESET:
7484 snprintf(evStr, EVENT_DESCR_STR_SZ,
7485 "SAS Device Status Change: Internal Device "
7486 "Reset Completed: id=%d channel=%d", id, channel);
7488 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7489 snprintf(evStr, EVENT_DESCR_STR_SZ,
7490 "SAS Device Status Change: Internal Task "
7491 "Abort : id=%d channel=%d", id, channel);
7493 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7494 snprintf(evStr, EVENT_DESCR_STR_SZ,
7495 "SAS Device Status Change: Internal Abort "
7496 "Task Set : id=%d channel=%d", id, channel);
7498 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7499 snprintf(evStr, EVENT_DESCR_STR_SZ,
7500 "SAS Device Status Change: Internal Clear "
7501 "Task Set : id=%d channel=%d", id, channel);
7503 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7504 snprintf(evStr, EVENT_DESCR_STR_SZ,
7505 "SAS Device Status Change: Internal Query "
7506 "Task : id=%d channel=%d", id, channel);
7508 case MPI_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
7509 snprintf(evStr, EVENT_DESCR_STR_SZ,
7510 "SAS Device Status Change: Async Notification "
7511 "Task : id=%d channel=%d", id, channel);
7514 snprintf(evStr, EVENT_DESCR_STR_SZ,
7515 "SAS Device Status Change: Unknown: "
7516 "id=%d channel=%d", id, channel);
7521 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7522 ds = "Bus Timer Expired";
7524 case MPI_EVENT_QUEUE_FULL:
7526 u16 curr_depth = (u16)(evData0 >> 16);
7527 u8 channel = (u8)(evData0 >> 8);
7528 u8 id = (u8)(evData0);
7530 snprintf(evStr, EVENT_DESCR_STR_SZ,
7531 "Queue Full: channel=%d id=%d depth=%d",
7532 channel, id, curr_depth);
7535 case MPI_EVENT_SAS_SES:
7536 ds = "SAS SES Event";
7538 case MPI_EVENT_PERSISTENT_TABLE_FULL:
7539 ds = "Persistent Table Full";
7541 case MPI_EVENT_SAS_PHY_LINK_STATUS:
7543 u8 LinkRates = (u8)(evData0 >> 8);
7544 u8 PhyNumber = (u8)(evData0);
7545 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7546 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7547 switch (LinkRates) {
7548 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7549 snprintf(evStr, EVENT_DESCR_STR_SZ,
7550 "SAS PHY Link Status: Phy=%d:"
7551 " Rate Unknown",PhyNumber);
7553 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7554 snprintf(evStr, EVENT_DESCR_STR_SZ,
7555 "SAS PHY Link Status: Phy=%d:"
7556 " Phy Disabled",PhyNumber);
7558 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7559 snprintf(evStr, EVENT_DESCR_STR_SZ,
7560 "SAS PHY Link Status: Phy=%d:"
7561 " Failed Speed Nego",PhyNumber);
7563 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7564 snprintf(evStr, EVENT_DESCR_STR_SZ,
7565 "SAS PHY Link Status: Phy=%d:"
7566 " Sata OOB Completed",PhyNumber);
7568 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7569 snprintf(evStr, EVENT_DESCR_STR_SZ,
7570 "SAS PHY Link Status: Phy=%d:"
7571 " Rate 1.5 Gbps",PhyNumber);
7573 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7574 snprintf(evStr, EVENT_DESCR_STR_SZ,
7575 "SAS PHY Link Status: Phy=%d:"
7576 " Rate 3.0 Gpbs",PhyNumber);
7579 snprintf(evStr, EVENT_DESCR_STR_SZ,
7580 "SAS PHY Link Status: Phy=%d", PhyNumber);
7585 case MPI_EVENT_SAS_DISCOVERY_ERROR:
7586 ds = "SAS Discovery Error";
7588 case MPI_EVENT_IR_RESYNC_UPDATE:
7590 u8 resync_complete = (u8)(evData0 >> 16);
7591 snprintf(evStr, EVENT_DESCR_STR_SZ,
7592 "IR Resync Update: Complete = %d:",resync_complete);
7597 u8 id = (u8)(evData0);
7598 u8 channel = (u8)(evData0 >> 8);
7599 u8 phys_num = (u8)(evData0 >> 24);
7600 u8 ReasonCode = (u8)(evData0 >> 16);
7602 switch (ReasonCode) {
7603 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7604 snprintf(evStr, EVENT_DESCR_STR_SZ,
7605 "IR2: LD State Changed: "
7606 "id=%d channel=%d phys_num=%d",
7607 id, channel, phys_num);
7609 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7610 snprintf(evStr, EVENT_DESCR_STR_SZ,
7611 "IR2: PD State Changed "
7612 "id=%d channel=%d phys_num=%d",
7613 id, channel, phys_num);
7615 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7616 snprintf(evStr, EVENT_DESCR_STR_SZ,
7617 "IR2: Bad Block Table Full: "
7618 "id=%d channel=%d phys_num=%d",
7619 id, channel, phys_num);
7621 case MPI_EVENT_IR2_RC_PD_INSERTED:
7622 snprintf(evStr, EVENT_DESCR_STR_SZ,
7623 "IR2: PD Inserted: "
7624 "id=%d channel=%d phys_num=%d",
7625 id, channel, phys_num);
7627 case MPI_EVENT_IR2_RC_PD_REMOVED:
7628 snprintf(evStr, EVENT_DESCR_STR_SZ,
7630 "id=%d channel=%d phys_num=%d",
7631 id, channel, phys_num);
7633 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7634 snprintf(evStr, EVENT_DESCR_STR_SZ,
7635 "IR2: Foreign CFG Detected: "
7636 "id=%d channel=%d phys_num=%d",
7637 id, channel, phys_num);
7639 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7640 snprintf(evStr, EVENT_DESCR_STR_SZ,
7641 "IR2: Rebuild Medium Error: "
7642 "id=%d channel=%d phys_num=%d",
7643 id, channel, phys_num);
7645 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7646 snprintf(evStr, EVENT_DESCR_STR_SZ,
7647 "IR2: Dual Port Added: "
7648 "id=%d channel=%d phys_num=%d",
7649 id, channel, phys_num);
7651 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7652 snprintf(evStr, EVENT_DESCR_STR_SZ,
7653 "IR2: Dual Port Removed: "
7654 "id=%d channel=%d phys_num=%d",
7655 id, channel, phys_num);
7663 case MPI_EVENT_SAS_DISCOVERY:
7666 ds = "SAS Discovery: Start";
7668 ds = "SAS Discovery: Stop";
7671 case MPI_EVENT_LOG_ENTRY_ADDED:
7672 ds = "SAS Log Entry Added";
7675 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7677 u8 phy_num = (u8)(evData0);
7678 u8 port_num = (u8)(evData0 >> 8);
7679 u8 num_phys = (u8)(evData0 >> 16);
7680 u8 primative = (u8)(evData0 >> 24);
7681 char *primative_str = NULL;
7683 switch (primative) {
7684 case MPI_EVENT_PRIMITIVE_CHANGE:
7685 primative_str = "change";
7687 case MPI_EVENT_PRIMITIVE_EXPANDER:
7688 primative_str = "expander";
7690 case MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT:
7691 primative_str = "asyn event";
7694 primative_str = "reserved";
7697 snprintf(evStr, EVENT_DESCR_STR_SZ,
7698 "SAS Broadcast Primative: phy=%d port=%d "
7699 "num_phys=%d primative=%s (0x%02x)",
7700 phy_num, port_num, num_phys, primative_str, primative);
7704 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7706 u8 reason = (u8)(evData0);
7709 case MPI_EVENT_SAS_INIT_RC_ADDED:
7710 ds = "SAS Initiator Status Change: Added";
7712 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7713 ds = "SAS Initiator Status Change: Deleted";
7716 ds = "SAS Initiator Status Change";
7722 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7724 u8 max_init = (u8)(evData0);
7725 u8 current_init = (u8)(evData0 >> 8);
7727 snprintf(evStr, EVENT_DESCR_STR_SZ,
7728 "SAS Initiator Device Table Overflow: max initiators=%02d "
7729 "current initators=%02d",
7730 max_init, current_init);
7733 case MPI_EVENT_SAS_SMP_ERROR:
7735 u8 status = (u8)(evData0);
7736 u8 port_num = (u8)(evData0 >> 8);
7737 u8 result = (u8)(evData0 >> 16);
7739 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7740 snprintf(evStr, EVENT_DESCR_STR_SZ,
7741 "SAS SMP Error: port=%d result=0x%02x",
7743 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7744 snprintf(evStr, EVENT_DESCR_STR_SZ,
7745 "SAS SMP Error: port=%d : CRC Error",
7747 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7748 snprintf(evStr, EVENT_DESCR_STR_SZ,
7749 "SAS SMP Error: port=%d : Timeout",
7751 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7752 snprintf(evStr, EVENT_DESCR_STR_SZ,
7753 "SAS SMP Error: port=%d : No Destination",
7755 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7756 snprintf(evStr, EVENT_DESCR_STR_SZ,
7757 "SAS SMP Error: port=%d : Bad Destination",
7760 snprintf(evStr, EVENT_DESCR_STR_SZ,
7761 "SAS SMP Error: port=%d : status=0x%02x",
7766 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7768 u8 reason = (u8)(evData0);
7771 case MPI_EVENT_SAS_EXP_RC_ADDED:
7772 ds = "Expander Status Change: Added";
7774 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7775 ds = "Expander Status Change: Deleted";
7778 ds = "Expander Status Change";
7785 * MPT base "custom" events may be added here...
7792 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7795 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7796 "MPT event:(%02Xh) : %s\n",
7797 ioc->name, event, evStr));
7799 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7800 ": Event data:\n"));
7801 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7802 devtverboseprintk(ioc, printk(" %08x",
7803 le32_to_cpu(pEventReply->Data[ii])));
7804 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7809 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7810 * @ioc: Pointer to MPT_ADAPTER structure
7811 * @pEventReply: Pointer to EventNotification reply frame
7812 * @evHandlers: Pointer to integer, number of event handlers
7814 * Routes a received EventNotificationReply to all currently registered
7816 * Returns sum of event handlers return values.
7819 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7830 * Do platform normalization of values
7832 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7833 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7835 evData0 = le32_to_cpu(pEventReply->Data[0]);
7838 #ifdef CONFIG_FUSION_LOGGING
7840 mpt_display_event_info(ioc, pEventReply);
7844 * Do general / base driver event processing
7847 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7849 u8 evState = evData0 & 0xFF;
7851 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7853 /* Update EventState field in cached IocFacts */
7854 if (ioc->facts.Function) {
7855 ioc->facts.EventState = evState;
7859 case MPI_EVENT_INTEGRATED_RAID:
7860 mptbase_raid_process_event_data(ioc,
7861 (MpiEventDataRaid_t *)pEventReply->Data);
7868 * Should this event be logged? Events are written sequentially.
7869 * When buffer is full, start again at the top.
7871 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7874 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7876 ioc->events[idx].event = event;
7877 ioc->events[idx].eventContext = ioc->eventContext;
7879 for (ii = 0; ii < 2; ii++) {
7881 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7883 ioc->events[idx].data[ii] = 0;
7886 ioc->eventContext++;
7891 * Call each currently registered protocol event handler.
7893 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7894 if (MptEvHandlers[cb_idx]) {
7895 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7896 "Routing Event to event handler #%d\n",
7897 ioc->name, cb_idx));
7898 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7902 /* FIXME? Examine results here? */
7905 * If needed, send (a single) EventAck.
7907 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7908 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7909 "EventAck required\n",ioc->name));
7910 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7911 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7916 *evHandlers = handlers;
7920 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7922 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7923 * @ioc: Pointer to MPT_ADAPTER structure
7924 * @log_info: U32 LogInfo reply word from the IOC
7926 * Refer to lsi/mpi_log_fc.h.
7929 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7931 char *desc = "unknown";
7933 switch (log_info & 0xFF000000) {
7934 case MPI_IOCLOGINFO_FC_INIT_BASE:
7935 desc = "FCP Initiator";
7937 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7938 desc = "FCP Target";
7940 case MPI_IOCLOGINFO_FC_LAN_BASE:
7943 case MPI_IOCLOGINFO_FC_MSG_BASE:
7944 desc = "MPI Message Layer";
7946 case MPI_IOCLOGINFO_FC_LINK_BASE:
7949 case MPI_IOCLOGINFO_FC_CTX_BASE:
7950 desc = "Context Manager";
7952 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7953 desc = "Invalid Field Offset";
7955 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7956 desc = "State Change Info";
7960 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7961 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7964 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7966 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7967 * @ioc: Pointer to MPT_ADAPTER structure
7968 * @log_info: U32 LogInfo word from the IOC
7970 * Refer to lsi/sp_log.h.
7973 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7975 u32 info = log_info & 0x00FF0000;
7976 char *desc = "unknown";
7980 desc = "bug! MID not found";
7984 desc = "Parity Error";
7988 desc = "ASYNC Outbound Overrun";
7992 desc = "SYNC Offset Error";
8000 desc = "Msg In Overflow";
8008 desc = "Outbound DMA Overrun";
8012 desc = "Task Management";
8016 desc = "Device Problem";
8020 desc = "Invalid Phase Change";
8024 desc = "Untagged Table Size";
8029 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
8032 /* strings for sas loginfo */
8033 static char *originator_str[] = {
8038 static char *iop_code_str[] = {
8040 "Invalid SAS Address", /* 01h */
8042 "Invalid Page", /* 03h */
8043 "Diag Message Error", /* 04h */
8044 "Task Terminated", /* 05h */
8045 "Enclosure Management", /* 06h */
8046 "Target Mode" /* 07h */
8048 static char *pl_code_str[] = {
8050 "Open Failure", /* 01h */
8051 "Invalid Scatter Gather List", /* 02h */
8052 "Wrong Relative Offset or Frame Length", /* 03h */
8053 "Frame Transfer Error", /* 04h */
8054 "Transmit Frame Connected Low", /* 05h */
8055 "SATA Non-NCQ RW Error Bit Set", /* 06h */
8056 "SATA Read Log Receive Data Error", /* 07h */
8057 "SATA NCQ Fail All Commands After Error", /* 08h */
8058 "SATA Error in Receive Set Device Bit FIS", /* 09h */
8059 "Receive Frame Invalid Message", /* 0Ah */
8060 "Receive Context Message Valid Error", /* 0Bh */
8061 "Receive Frame Current Frame Error", /* 0Ch */
8062 "SATA Link Down", /* 0Dh */
8063 "Discovery SATA Init W IOS", /* 0Eh */
8064 "Config Invalid Page", /* 0Fh */
8065 "Discovery SATA Init Timeout", /* 10h */
8068 "IO Not Yet Executed", /* 13h */
8069 "IO Executed", /* 14h */
8070 "Persistent Reservation Out Not Affiliation "
8072 "Open Transmit DMA Abort", /* 16h */
8073 "IO Device Missing Delay Retry", /* 17h */
8074 "IO Cancelled Due to Recieve Error", /* 18h */
8082 "Enclosure Management" /* 20h */
8084 static char *ir_code_str[] = {
8085 "Raid Action Error", /* 00h */
8095 static char *raid_sub_code_str[] = {
8097 "Volume Creation Failed: Data Passed too "
8099 "Volume Creation Failed: Duplicate Volumes "
8100 "Attempted", /* 02h */
8101 "Volume Creation Failed: Max Number "
8102 "Supported Volumes Exceeded", /* 03h */
8103 "Volume Creation Failed: DMA Error", /* 04h */
8104 "Volume Creation Failed: Invalid Volume Type", /* 05h */
8105 "Volume Creation Failed: Error Reading "
8106 "MFG Page 4", /* 06h */
8107 "Volume Creation Failed: Creating Internal "
8108 "Structures", /* 07h */
8117 "Activation failed: Already Active Volume", /* 10h */
8118 "Activation failed: Unsupported Volume Type", /* 11h */
8119 "Activation failed: Too Many Active Volumes", /* 12h */
8120 "Activation failed: Volume ID in Use", /* 13h */
8121 "Activation failed: Reported Failure", /* 14h */
8122 "Activation failed: Importing a Volume", /* 15h */
8133 "Phys Disk failed: Too Many Phys Disks", /* 20h */
8134 "Phys Disk failed: Data Passed too Large", /* 21h */
8135 "Phys Disk failed: DMA Error", /* 22h */
8136 "Phys Disk failed: Invalid <channel:id>", /* 23h */
8137 "Phys Disk failed: Creating Phys Disk Config "
8150 "Compatibility Error: IR Disabled", /* 30h */
8151 "Compatibility Error: Inquiry Comand Failed", /* 31h */
8152 "Compatibility Error: Device not Direct Access "
8153 "Device ", /* 32h */
8154 "Compatibility Error: Removable Device Found", /* 33h */
8155 "Compatibility Error: Device SCSI Version not "
8156 "2 or Higher", /* 34h */
8157 "Compatibility Error: SATA Device, 48 BIT LBA "
8158 "not Supported", /* 35h */
8159 "Compatibility Error: Device doesn't have "
8160 "512 Byte Block Sizes", /* 36h */
8161 "Compatibility Error: Volume Type Check Failed", /* 37h */
8162 "Compatibility Error: Volume Type is "
8163 "Unsupported by FW", /* 38h */
8164 "Compatibility Error: Disk Drive too Small for "
8165 "use in Volume", /* 39h */
8166 "Compatibility Error: Phys Disk for Create "
8167 "Volume not Found", /* 3Ah */
8168 "Compatibility Error: Too Many or too Few "
8169 "Disks for Volume Type", /* 3Bh */
8170 "Compatibility Error: Disk stripe Sizes "
8171 "Must be 64KB", /* 3Ch */
8172 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8175 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8177 * mpt_sas_log_info - Log information returned from SAS IOC.
8178 * @ioc: Pointer to MPT_ADAPTER structure
8179 * @log_info: U32 LogInfo reply word from the IOC
8181 * Refer to lsi/mpi_log_sas.h.
8184 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
8186 union loginfo_type {
8195 union loginfo_type sas_loginfo;
8196 char *originator_desc = NULL;
8197 char *code_desc = NULL;
8198 char *sub_code_desc = NULL;
8200 sas_loginfo.loginfo = log_info;
8201 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8202 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8205 originator_desc = originator_str[sas_loginfo.dw.originator];
8207 switch (sas_loginfo.dw.originator) {
8210 if (sas_loginfo.dw.code <
8211 ARRAY_SIZE(iop_code_str))
8212 code_desc = iop_code_str[sas_loginfo.dw.code];
8215 if (sas_loginfo.dw.code <
8216 ARRAY_SIZE(pl_code_str))
8217 code_desc = pl_code_str[sas_loginfo.dw.code];
8220 if (sas_loginfo.dw.code >=
8221 ARRAY_SIZE(ir_code_str))
8223 code_desc = ir_code_str[sas_loginfo.dw.code];
8224 if (sas_loginfo.dw.subcode >=
8225 ARRAY_SIZE(raid_sub_code_str))
8227 if (sas_loginfo.dw.code == 0)
8229 raid_sub_code_str[sas_loginfo.dw.subcode];
8235 if (sub_code_desc != NULL)
8236 printk(MYIOC_s_INFO_FMT
8237 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8239 ioc->name, log_info, originator_desc, code_desc,
8241 else if (code_desc != NULL)
8242 printk(MYIOC_s_INFO_FMT
8243 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8244 " SubCode(0x%04x)\n",
8245 ioc->name, log_info, originator_desc, code_desc,
8246 sas_loginfo.dw.subcode);
8248 printk(MYIOC_s_INFO_FMT
8249 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8250 " SubCode(0x%04x)\n",
8251 ioc->name, log_info, originator_desc,
8252 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
8255 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8257 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8258 * @ioc: Pointer to MPT_ADAPTER structure
8259 * @ioc_status: U32 IOCStatus word from IOC
8260 * @mf: Pointer to MPT request frame
8262 * Refer to lsi/mpi.h.
8265 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8267 Config_t *pReq = (Config_t *)mf;
8268 char extend_desc[EVENT_DESCR_STR_SZ];
8273 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8274 page_type = pReq->ExtPageType;
8276 page_type = pReq->Header.PageType;
8279 * ignore invalid page messages for GET_NEXT_HANDLE
8281 form = le32_to_cpu(pReq->PageAddress);
8282 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8283 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8284 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8285 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8286 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8287 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8290 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8291 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8292 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8296 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8297 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8298 page_type, pReq->Header.PageNumber, pReq->Action, form);
8300 switch (ioc_status) {
8302 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8303 desc = "Config Page Invalid Action";
8306 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8307 desc = "Config Page Invalid Type";
8310 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8311 desc = "Config Page Invalid Page";
8314 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8315 desc = "Config Page Invalid Data";
8318 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8319 desc = "Config Page No Defaults";
8322 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8323 desc = "Config Page Can't Commit";
8330 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8331 ioc->name, ioc_status, desc, extend_desc));
8335 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8336 * @ioc: Pointer to MPT_ADAPTER structure
8337 * @ioc_status: U32 IOCStatus word from IOC
8338 * @mf: Pointer to MPT request frame
8340 * Refer to lsi/mpi.h.
8343 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8345 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8350 /****************************************************************************/
8351 /* Common IOCStatus values for all replies */
8352 /****************************************************************************/
8354 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8355 desc = "Invalid Function";
8358 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8362 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8363 desc = "Invalid SGL";
8366 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8367 desc = "Internal Error";
8370 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8374 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8375 desc = "Insufficient Resources";
8378 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8379 desc = "Invalid Field";
8382 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8383 desc = "Invalid State";
8386 /****************************************************************************/
8387 /* Config IOCStatus values */
8388 /****************************************************************************/
8390 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8391 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8392 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8393 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8394 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8395 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8396 mpt_iocstatus_info_config(ioc, status, mf);
8399 /****************************************************************************/
8400 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8402 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8404 /****************************************************************************/
8406 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8407 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8408 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8409 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8410 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8411 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8412 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8413 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8414 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8415 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8416 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8417 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8418 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8421 /****************************************************************************/
8422 /* SCSI Target values */
8423 /****************************************************************************/
8425 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8426 desc = "Target: Priority IO";
8429 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8430 desc = "Target: Invalid Port";
8433 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8434 desc = "Target Invalid IO Index:";
8437 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8438 desc = "Target: Aborted";
8441 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8442 desc = "Target: No Conn Retryable";
8445 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8446 desc = "Target: No Connection";
8449 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8450 desc = "Target: Transfer Count Mismatch";
8453 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8454 desc = "Target: STS Data not Sent";
8457 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8458 desc = "Target: Data Offset Error";
8461 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8462 desc = "Target: Too Much Write Data";
8465 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8466 desc = "Target: IU Too Short";
8469 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8470 desc = "Target: ACK NAK Timeout";
8473 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8474 desc = "Target: Nak Received";
8477 /****************************************************************************/
8478 /* Fibre Channel Direct Access values */
8479 /****************************************************************************/
8481 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8482 desc = "FC: Aborted";
8485 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8486 desc = "FC: RX ID Invalid";
8489 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8490 desc = "FC: DID Invalid";
8493 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8494 desc = "FC: Node Logged Out";
8497 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8498 desc = "FC: Exchange Canceled";
8501 /****************************************************************************/
8503 /****************************************************************************/
8505 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8506 desc = "LAN: Device not Found";
8509 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8510 desc = "LAN: Device Failure";
8513 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8514 desc = "LAN: Transmit Error";
8517 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8518 desc = "LAN: Transmit Aborted";
8521 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8522 desc = "LAN: Receive Error";
8525 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8526 desc = "LAN: Receive Aborted";
8529 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8530 desc = "LAN: Partial Packet";
8533 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8534 desc = "LAN: Canceled";
8537 /****************************************************************************/
8538 /* Serial Attached SCSI values */
8539 /****************************************************************************/
8541 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8542 desc = "SAS: SMP Request Failed";
8545 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8546 desc = "SAS: SMP Data Overrun";
8557 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8558 ioc->name, status, desc));
8561 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8562 EXPORT_SYMBOL(mpt_attach);
8563 EXPORT_SYMBOL(mpt_detach);
8565 EXPORT_SYMBOL(mpt_resume);
8566 EXPORT_SYMBOL(mpt_suspend);
8568 EXPORT_SYMBOL(ioc_list);
8569 EXPORT_SYMBOL(mpt_proc_root_dir);
8570 EXPORT_SYMBOL(mpt_register);
8571 EXPORT_SYMBOL(mpt_deregister);
8572 EXPORT_SYMBOL(mpt_event_register);
8573 EXPORT_SYMBOL(mpt_event_deregister);
8574 EXPORT_SYMBOL(mpt_reset_register);
8575 EXPORT_SYMBOL(mpt_reset_deregister);
8576 EXPORT_SYMBOL(mpt_device_driver_register);
8577 EXPORT_SYMBOL(mpt_device_driver_deregister);
8578 EXPORT_SYMBOL(mpt_get_msg_frame);
8579 EXPORT_SYMBOL(mpt_put_msg_frame);
8580 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8581 EXPORT_SYMBOL(mpt_free_msg_frame);
8582 EXPORT_SYMBOL(mpt_send_handshake_request);
8583 EXPORT_SYMBOL(mpt_verify_adapter);
8584 EXPORT_SYMBOL(mpt_GetIocState);
8585 EXPORT_SYMBOL(mpt_print_ioc_summary);
8586 EXPORT_SYMBOL(mpt_HardResetHandler);
8587 EXPORT_SYMBOL(mpt_SoftResetHandler);
8588 EXPORT_SYMBOL(mpt_config);
8589 EXPORT_SYMBOL(mpt_findImVolumes);
8590 EXPORT_SYMBOL(mpt_alloc_fw_memory);
8591 EXPORT_SYMBOL(mpt_free_fw_memory);
8592 EXPORT_SYMBOL(mptbase_sas_persist_operation);
8593 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8594 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
8595 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
8596 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
8597 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
8598 EXPORT_SYMBOL(mpt_halt_firmware);
8599 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8601 * fusion_init - Fusion MPT base driver initialization routine.
8603 * Returns 0 for success, non-zero for failure.
8610 show_mptmod_ver(my_NAME, my_VERSION);
8611 printk(KERN_INFO COPYRIGHT "\n");
8613 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8614 MptCallbacks[cb_idx] = NULL;
8615 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8616 MptEvHandlers[cb_idx] = NULL;
8617 MptResetHandlers[cb_idx] = NULL;
8620 /* Register ourselves (mptbase) in order to facilitate
8621 * EventNotification handling.
8623 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);
8625 /* Register for hard reset handling callbacks.
8627 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8629 #ifdef CONFIG_PROC_FS
8630 (void) procmpt_create();
8635 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8637 * fusion_exit - Perform driver unload cleanup.
8639 * This routine frees all resources associated with each MPT adapter
8640 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8646 mpt_reset_deregister(mpt_base_index);
8648 #ifdef CONFIG_PROC_FS
8653 module_init(fusion_init);
8654 module_exit(fusion_exit);