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
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/seq_file.h>
54 #include <linux/slab.h>
55 #include <linux/types.h>
56 #include <linux/pci.h>
57 #include <linux/kdev_t.h>
58 #include <linux/blkdev.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
61 #include <linux/dma-mapping.h>
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)");
104 static int mpt_debug_level;
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 \
111 int mpt_fwfault_debug;
112 EXPORT_SYMBOL(mpt_fwfault_debug);
113 module_param(mpt_fwfault_debug, int, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)");
118 static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS][50];
121 static int mfcounter = 0;
122 #define PRINT_MF_COUNT 20000
125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
130 #define WHOINIT_UNKNOWN 0xAA
132 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
136 /* Adapter link list */
138 /* Callback lookup table */
139 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
140 /* Protocol driver class lookup table */
141 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
142 /* Event handler lookup table */
143 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
144 /* Reset handler lookup table */
145 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
146 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
148 #ifdef CONFIG_PROC_FS
149 static struct proc_dir_entry *mpt_proc_root_dir;
153 * Driver Callback Index's
155 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
156 static u8 last_drv_idx;
158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
162 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
163 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
164 MPT_FRAME_HDR *reply);
165 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
166 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
168 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
169 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
170 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
171 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
173 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
174 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
175 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
176 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
177 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
178 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
179 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
180 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
181 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
182 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
183 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
184 static int PrimeIocFifos(MPT_ADAPTER *ioc);
185 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
187 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
188 static int GetLanConfigPages(MPT_ADAPTER *ioc);
189 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
190 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
191 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
192 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
193 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
194 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
195 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
196 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
198 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
199 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
200 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
202 #ifdef CONFIG_PROC_FS
203 static const struct file_operations mpt_summary_proc_fops;
204 static const struct file_operations mpt_version_proc_fops;
205 static const struct file_operations mpt_iocinfo_proc_fops;
207 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
209 static int ProcessEventNotification(MPT_ADAPTER *ioc,
210 EventNotificationReply_t *evReply, int *evHandlers);
211 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
212 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
213 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
214 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
215 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
216 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
218 /* module entry point */
219 static int __init fusion_init (void);
220 static void __exit fusion_exit (void);
222 #define CHIPREG_READ32(addr) readl_relaxed(addr)
223 #define CHIPREG_READ32_dmasync(addr) readl(addr)
224 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
225 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
226 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
229 pci_disable_io_access(struct pci_dev *pdev)
233 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
235 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
239 pci_enable_io_access(struct pci_dev *pdev)
243 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
245 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
248 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
250 int ret = param_set_int(val, kp);
256 list_for_each_entry(ioc, &ioc_list, list)
257 ioc->debug_level = mpt_debug_level;
262 * mpt_get_cb_idx - obtain cb_idx for registered driver
263 * @dclass: class driver enum
265 * Returns cb_idx, or zero means it wasn't found
268 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
272 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
273 if (MptDriverClass[cb_idx] == dclass)
279 * mpt_is_discovery_complete - determine if discovery has completed
280 * @ioc: per adatper instance
282 * Returns 1 when discovery completed, else zero.
285 mpt_is_discovery_complete(MPT_ADAPTER *ioc)
287 ConfigExtendedPageHeader_t hdr;
289 SasIOUnitPage0_t *buffer;
290 dma_addr_t dma_handle;
293 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
294 memset(&cfg, 0, sizeof(CONFIGPARMS));
295 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
296 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
297 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
298 cfg.cfghdr.ehdr = &hdr;
299 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
301 if ((mpt_config(ioc, &cfg)))
303 if (!hdr.ExtPageLength)
306 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
311 cfg.physAddr = dma_handle;
312 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
314 if ((mpt_config(ioc, &cfg)))
315 goto out_free_consistent;
317 if (!(buffer->PhyData[0].PortFlags &
318 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
322 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
329 * mpt_fault_reset_work - work performed on workq after ioc fault
330 * @work: input argument, used to derive ioc
334 mpt_fault_reset_work(struct work_struct *work)
337 container_of(work, MPT_ADAPTER, fault_reset_work.work);
342 if (ioc->ioc_reset_in_progress || !ioc->active)
345 ioc_raw_state = mpt_GetIocState(ioc, 0);
346 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
347 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
348 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
349 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
350 ioc->name, __func__);
351 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
352 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
353 __func__, (rc == 0) ? "success" : "failed");
354 ioc_raw_state = mpt_GetIocState(ioc, 0);
355 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
356 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
357 "reset (%04xh)\n", ioc->name, ioc_raw_state &
358 MPI_DOORBELL_DATA_MASK);
359 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
360 if ((mpt_is_discovery_complete(ioc))) {
361 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
362 "discovery_quiesce_io flag\n", ioc->name));
363 ioc->sas_discovery_quiesce_io = 0;
369 * Take turns polling alternate controller
374 /* rearm the timer */
375 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
376 if (ioc->reset_work_q)
377 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
378 msecs_to_jiffies(MPT_POLLING_INTERVAL));
379 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
384 * Process turbo (context) reply...
387 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
389 MPT_FRAME_HDR *mf = NULL;
390 MPT_FRAME_HDR *mr = NULL;
394 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
397 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
398 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
399 req_idx = pa & 0x0000FFFF;
400 cb_idx = (pa & 0x00FF0000) >> 16;
401 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
403 case MPI_CONTEXT_REPLY_TYPE_LAN:
404 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
406 * Blind set of mf to NULL here was fatal
407 * after lan_reply says "freeme"
408 * Fix sort of combined with an optimization here;
409 * added explicit check for case where lan_reply
410 * was just returning 1 and doing nothing else.
411 * For this case skip the callback, but set up
412 * proper mf value first here:-)
414 if ((pa & 0x58000000) == 0x58000000) {
415 req_idx = pa & 0x0000FFFF;
416 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
417 mpt_free_msg_frame(ioc, mf);
422 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
424 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
425 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
426 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
433 /* Check for (valid) IO callback! */
434 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
435 MptCallbacks[cb_idx] == NULL) {
436 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
437 __func__, ioc->name, cb_idx);
441 if (MptCallbacks[cb_idx](ioc, mf, mr))
442 mpt_free_msg_frame(ioc, mf);
448 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
459 /* non-TURBO reply! Hmmm, something may be up...
460 * Newest turbo reply mechanism; get address
461 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
464 /* Map DMA address of reply header to cpu address.
465 * pa is 32 bits - but the dma address may be 32 or 64 bits
466 * get offset based only only the low addresses
469 reply_dma_low = (pa <<= 1);
470 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
471 (reply_dma_low - ioc->reply_frames_low_dma));
473 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
474 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
475 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
477 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
478 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
479 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
481 /* Check/log IOC log info
483 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
484 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
485 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
486 if (ioc->bus_type == FC)
487 mpt_fc_log_info(ioc, log_info);
488 else if (ioc->bus_type == SPI)
489 mpt_spi_log_info(ioc, log_info);
490 else if (ioc->bus_type == SAS)
491 mpt_sas_log_info(ioc, log_info, cb_idx);
494 if (ioc_stat & MPI_IOCSTATUS_MASK)
495 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
497 /* Check for (valid) IO callback! */
498 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
499 MptCallbacks[cb_idx] == NULL) {
500 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
501 __func__, ioc->name, cb_idx);
506 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
509 /* Flush (non-TURBO) reply with a WRITE! */
510 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
513 mpt_free_msg_frame(ioc, mf);
517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
519 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
520 * @irq: irq number (not used)
521 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
523 * This routine is registered via the request_irq() kernel API call,
524 * and handles all interrupts generated from a specific MPT adapter
525 * (also referred to as a IO Controller or IOC).
526 * This routine must clear the interrupt from the adapter and does
527 * so by reading the reply FIFO. Multiple replies may be processed
528 * per single call to this routine.
530 * This routine handles register-level access of the adapter but
531 * dispatches (calls) a protocol-specific callback routine to handle
532 * the protocol-specific details of the MPT request completion.
535 mpt_interrupt(int irq, void *bus_id)
537 MPT_ADAPTER *ioc = bus_id;
538 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
540 if (pa == 0xFFFFFFFF)
544 * Drain the reply FIFO!
547 if (pa & MPI_ADDRESS_REPLY_A_BIT)
550 mpt_turbo_reply(ioc, pa);
551 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
552 } while (pa != 0xFFFFFFFF);
557 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
559 * mptbase_reply - MPT base driver's callback routine
560 * @ioc: Pointer to MPT_ADAPTER structure
561 * @req: Pointer to original MPT request frame
562 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
564 * MPT base driver's callback routine; all base driver
565 * "internal" request/reply processing is routed here.
566 * Currently used for EventNotification and EventAck handling.
568 * Returns 1 indicating original alloc'd request frame ptr
569 * should be freed, or 0 if it shouldn't.
572 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
574 EventNotificationReply_t *pEventReply;
579 switch (reply->u.hdr.Function) {
580 case MPI_FUNCTION_EVENT_NOTIFICATION:
581 pEventReply = (EventNotificationReply_t *)reply;
583 ProcessEventNotification(ioc, pEventReply, &evHandlers);
584 event = le32_to_cpu(pEventReply->Event) & 0xFF;
585 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
587 if (event != MPI_EVENT_EVENT_CHANGE)
589 case MPI_FUNCTION_CONFIG:
590 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
591 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
593 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
594 memcpy(ioc->mptbase_cmds.reply, reply,
595 min(MPT_DEFAULT_FRAME_SIZE,
596 4 * reply->u.reply.MsgLength));
598 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
599 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
600 complete(&ioc->mptbase_cmds.done);
603 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
606 case MPI_FUNCTION_EVENT_ACK:
607 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
608 "EventAck reply received\n", ioc->name));
611 printk(MYIOC_s_ERR_FMT
612 "Unexpected msg function (=%02Xh) reply received!\n",
613 ioc->name, reply->u.hdr.Function);
618 * Conditionally tell caller to free the original
619 * EventNotification/EventAck/unexpected request frame!
624 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
626 * mpt_register - Register protocol-specific main callback handler.
627 * @cbfunc: callback function pointer
628 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
630 * This routine is called by a protocol-specific driver (SCSI host,
631 * LAN, SCSI target) to register its reply callback routine. Each
632 * protocol-specific driver must do this before it will be able to
633 * use any IOC resources, such as obtaining request frames.
635 * NOTES: The SCSI protocol driver currently calls this routine thrice
636 * in order to register separate callbacks; one for "normal" SCSI IO;
637 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
639 * Returns u8 valued "handle" in the range (and S.O.D. order)
640 * {N,...,7,6,5,...,1} if successful.
641 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
642 * considered an error by the caller.
645 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
648 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
651 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
652 * (slot/handle 0 is reserved!)
654 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
655 if (MptCallbacks[cb_idx] == NULL) {
656 MptCallbacks[cb_idx] = cbfunc;
657 MptDriverClass[cb_idx] = dclass;
658 MptEvHandlers[cb_idx] = NULL;
659 last_drv_idx = cb_idx;
660 memcpy(MptCallbacksName[cb_idx], func_name,
661 strlen(func_name) > 50 ? 50 : strlen(func_name));
669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
671 * mpt_deregister - Deregister a protocol drivers resources.
672 * @cb_idx: previously registered callback handle
674 * Each protocol-specific driver should call this routine when its
675 * module is unloaded.
678 mpt_deregister(u8 cb_idx)
680 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
681 MptCallbacks[cb_idx] = NULL;
682 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
683 MptEvHandlers[cb_idx] = NULL;
689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
691 * mpt_event_register - Register protocol-specific event callback handler.
692 * @cb_idx: previously registered (via mpt_register) callback handle
693 * @ev_cbfunc: callback function
695 * This routine can be called by one or more protocol-specific drivers
696 * if/when they choose to be notified of MPT events.
698 * Returns 0 for success.
701 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
703 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
706 MptEvHandlers[cb_idx] = ev_cbfunc;
710 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
712 * mpt_event_deregister - Deregister protocol-specific event callback handler
713 * @cb_idx: previously registered callback handle
715 * Each protocol-specific driver should call this routine
716 * when it does not (or can no longer) handle events,
717 * or when its module is unloaded.
720 mpt_event_deregister(u8 cb_idx)
722 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
725 MptEvHandlers[cb_idx] = NULL;
728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
730 * mpt_reset_register - Register protocol-specific IOC reset handler.
731 * @cb_idx: previously registered (via mpt_register) callback handle
732 * @reset_func: reset function
734 * This routine can be called by one or more protocol-specific drivers
735 * if/when they choose to be notified of IOC resets.
737 * Returns 0 for success.
740 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
742 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
745 MptResetHandlers[cb_idx] = reset_func;
749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
751 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
752 * @cb_idx: previously registered callback handle
754 * Each protocol-specific driver should call this routine
755 * when it does not (or can no longer) handle IOC reset handling,
756 * or when its module is unloaded.
759 mpt_reset_deregister(u8 cb_idx)
761 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
764 MptResetHandlers[cb_idx] = NULL;
767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
769 * mpt_device_driver_register - Register device driver hooks
770 * @dd_cbfunc: driver callbacks struct
771 * @cb_idx: MPT protocol driver index
774 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
777 const struct pci_device_id *id;
779 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
782 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
784 /* call per pci device probe entry point */
785 list_for_each_entry(ioc, &ioc_list, list) {
786 id = ioc->pcidev->driver ?
787 ioc->pcidev->driver->id_table : NULL;
788 if (dd_cbfunc->probe)
789 dd_cbfunc->probe(ioc->pcidev, id);
795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
797 * mpt_device_driver_deregister - DeRegister device driver hooks
798 * @cb_idx: MPT protocol driver index
801 mpt_device_driver_deregister(u8 cb_idx)
803 struct mpt_pci_driver *dd_cbfunc;
806 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
809 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
811 list_for_each_entry(ioc, &ioc_list, list) {
812 if (dd_cbfunc->remove)
813 dd_cbfunc->remove(ioc->pcidev);
816 MptDeviceDriverHandlers[cb_idx] = NULL;
820 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
822 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
823 * @cb_idx: Handle of registered MPT protocol driver
824 * @ioc: Pointer to MPT adapter structure
826 * Obtain an MPT request frame from the pool (of 1024) that are
827 * allocated per MPT adapter.
829 * Returns pointer to a MPT request frame or %NULL if none are available
830 * or IOC is not active.
833 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
837 u16 req_idx; /* Request index */
839 /* validate handle and ioc identifier */
843 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
844 "returning NULL!\n", ioc->name);
847 /* If interrupts are not attached, do not return a request frame */
851 spin_lock_irqsave(&ioc->FreeQlock, flags);
852 if (!list_empty(&ioc->FreeQ)) {
855 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
856 u.frame.linkage.list);
857 list_del(&mf->u.frame.linkage.list);
858 mf->u.frame.linkage.arg1 = 0;
859 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
860 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
862 req_idx = req_offset / ioc->req_sz;
863 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
864 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
865 /* Default, will be changed if necessary in SG generation */
866 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
873 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
877 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
878 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
881 if (mfcounter == PRINT_MF_COUNT)
882 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
883 ioc->mfcnt, ioc->req_depth);
886 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
887 ioc->name, cb_idx, ioc->id, mf));
891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
893 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
894 * @cb_idx: Handle of registered MPT protocol driver
895 * @ioc: Pointer to MPT adapter structure
896 * @mf: Pointer to MPT request frame
898 * This routine posts an MPT request frame to the request post FIFO of a
899 * specific MPT adapter.
902 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
906 u16 req_idx; /* Request index */
908 /* ensure values are reset properly! */
909 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
910 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
912 req_idx = req_offset / ioc->req_sz;
913 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
914 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
916 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
918 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
919 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
920 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
921 ioc->RequestNB[req_idx]));
922 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
926 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
927 * @cb_idx: Handle of registered MPT protocol driver
928 * @ioc: Pointer to MPT adapter structure
929 * @mf: Pointer to MPT request frame
931 * Send a protocol-specific MPT request frame to an IOC using
932 * hi-priority request queue.
934 * This routine posts an MPT request frame to the request post FIFO of a
935 * specific MPT adapter.
938 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
942 u16 req_idx; /* Request index */
944 /* ensure values are reset properly! */
945 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
946 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
947 req_idx = req_offset / ioc->req_sz;
948 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
949 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
951 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
953 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
954 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
955 ioc->name, mf_dma_addr, req_idx));
956 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
961 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
962 * @ioc: Pointer to MPT adapter structure
963 * @mf: Pointer to MPT request frame
965 * This routine places a MPT request frame back on the MPT adapter's
969 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
973 /* Put Request back on FreeQ! */
974 spin_lock_irqsave(&ioc->FreeQlock, flags);
975 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
977 /* signature to know if this mf is freed */
978 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
979 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
984 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
989 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
990 * @pAddr: virtual address for SGE
991 * @flagslength: SGE flags and data transfer length
992 * @dma_addr: Physical address
994 * This routine places a MPT request frame back on the MPT adapter's
998 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1000 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1001 pSge->FlagsLength = cpu_to_le32(flagslength);
1002 pSge->Address = cpu_to_le32(dma_addr);
1006 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1007 * @pAddr: virtual address for SGE
1008 * @flagslength: SGE flags and data transfer length
1009 * @dma_addr: Physical address
1011 * This routine places a MPT request frame back on the MPT adapter's
1015 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1017 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1018 pSge->Address.Low = cpu_to_le32
1019 (lower_32_bits(dma_addr));
1020 pSge->Address.High = cpu_to_le32
1021 (upper_32_bits(dma_addr));
1022 pSge->FlagsLength = cpu_to_le32
1023 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1027 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1028 * @pAddr: virtual address for SGE
1029 * @flagslength: SGE flags and data transfer length
1030 * @dma_addr: Physical address
1032 * This routine places a MPT request frame back on the MPT adapter's
1036 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1038 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1041 pSge->Address.Low = cpu_to_le32
1042 (lower_32_bits(dma_addr));
1043 tmp = (u32)(upper_32_bits(dma_addr));
1046 * 1078 errata workaround for the 36GB limitation
1048 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1050 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1052 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1053 printk(KERN_DEBUG "1078 P0M2 addressing for "
1054 "addr = 0x%llx len = %d\n",
1055 (unsigned long long)dma_addr,
1056 MPI_SGE_LENGTH(flagslength));
1059 pSge->Address.High = cpu_to_le32(tmp);
1060 pSge->FlagsLength = cpu_to_le32(
1061 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1066 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1067 * @pAddr: virtual address for SGE
1068 * @next: nextChainOffset value (u32's)
1069 * @length: length of next SGL segment
1070 * @dma_addr: Physical address
1074 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1076 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1077 pChain->Length = cpu_to_le16(length);
1078 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1079 pChain->NextChainOffset = next;
1080 pChain->Address = cpu_to_le32(dma_addr);
1083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1085 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1086 * @pAddr: virtual address for SGE
1087 * @next: nextChainOffset value (u32's)
1088 * @length: length of next SGL segment
1089 * @dma_addr: Physical address
1093 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1095 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1096 u32 tmp = dma_addr & 0xFFFFFFFF;
1098 pChain->Length = cpu_to_le16(length);
1099 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1100 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1102 pChain->NextChainOffset = next;
1104 pChain->Address.Low = cpu_to_le32(tmp);
1105 tmp = (u32)(upper_32_bits(dma_addr));
1106 pChain->Address.High = cpu_to_le32(tmp);
1109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1111 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1112 * @cb_idx: Handle of registered MPT protocol driver
1113 * @ioc: Pointer to MPT adapter structure
1114 * @reqBytes: Size of the request in bytes
1115 * @req: Pointer to MPT request frame
1116 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1118 * This routine is used exclusively to send MptScsiTaskMgmt
1119 * requests since they are required to be sent via doorbell handshake.
1121 * NOTE: It is the callers responsibility to byte-swap fields in the
1122 * request which are greater than 1 byte in size.
1124 * Returns 0 for success, non-zero for failure.
1127 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1133 /* State is known to be good upon entering
1134 * this function so issue the bus reset
1139 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1140 * setting cb_idx/req_idx. But ONLY if this request
1141 * is in proper (pre-alloc'd) request buffer range...
1143 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1144 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1145 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1146 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1147 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1150 /* Make sure there are no doorbells */
1151 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1153 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1154 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1155 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1157 /* Wait for IOC doorbell int */
1158 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1162 /* Read doorbell and check for active bit */
1163 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1166 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1169 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1171 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1175 /* Send request via doorbell handshake */
1176 req_as_bytes = (u8 *) req;
1177 for (ii = 0; ii < reqBytes/4; ii++) {
1180 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1181 (req_as_bytes[(ii*4) + 1] << 8) |
1182 (req_as_bytes[(ii*4) + 2] << 16) |
1183 (req_as_bytes[(ii*4) + 3] << 24));
1184 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1185 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1191 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1196 /* Make sure there are no doorbells */
1197 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1204 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1205 * @ioc: Pointer to MPT adapter structure
1206 * @access_control_value: define bits below
1207 * @sleepFlag: Specifies whether the process can sleep
1209 * Provides mechanism for the host driver to control the IOC's
1210 * Host Page Buffer access.
1212 * Access Control Value - bits[15:12]
1214 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1215 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1216 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1218 * Returns 0 for success, non-zero for failure.
1222 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1226 /* return if in use */
1227 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1228 & MPI_DOORBELL_ACTIVE)
1231 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1233 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1234 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1235 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1236 (access_control_value<<12)));
1238 /* Wait for IOC to clear Doorbell Status bit */
1239 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1247 * mpt_host_page_alloc - allocate system memory for the fw
1248 * @ioc: Pointer to pointer to IOC adapter
1249 * @ioc_init: Pointer to ioc init config page
1251 * If we already allocated memory in past, then resend the same pointer.
1252 * Returns 0 for success, non-zero for failure.
1255 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1259 u32 host_page_buffer_sz=0;
1261 if(!ioc->HostPageBuffer) {
1263 host_page_buffer_sz =
1264 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1266 if(!host_page_buffer_sz)
1267 return 0; /* fw doesn't need any host buffers */
1269 /* spin till we get enough memory */
1270 while(host_page_buffer_sz > 0) {
1272 if((ioc->HostPageBuffer = pci_alloc_consistent(
1274 host_page_buffer_sz,
1275 &ioc->HostPageBuffer_dma)) != NULL) {
1277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1278 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1279 ioc->name, ioc->HostPageBuffer,
1280 (u32)ioc->HostPageBuffer_dma,
1281 host_page_buffer_sz));
1282 ioc->alloc_total += host_page_buffer_sz;
1283 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1287 host_page_buffer_sz -= (4*1024);
1291 if(!ioc->HostPageBuffer) {
1292 printk(MYIOC_s_ERR_FMT
1293 "Failed to alloc memory for host_page_buffer!\n",
1298 psge = (char *)&ioc_init->HostPageBufferSGE;
1299 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1300 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1301 MPI_SGE_FLAGS_HOST_TO_IOC |
1302 MPI_SGE_FLAGS_END_OF_BUFFER;
1303 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1304 flags_length |= ioc->HostPageBuffer_sz;
1305 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1306 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1311 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1313 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1314 * @iocid: IOC unique identifier (integer)
1315 * @iocpp: Pointer to pointer to IOC adapter
1317 * Given a unique IOC identifier, set pointer to the associated MPT
1318 * adapter structure.
1320 * Returns iocid and sets iocpp if iocid is found.
1321 * Returns -1 if iocid is not found.
1324 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1328 list_for_each_entry(ioc,&ioc_list,list) {
1329 if (ioc->id == iocid) {
1340 * mpt_get_product_name - returns product string
1341 * @vendor: pci vendor id
1342 * @device: pci device id
1343 * @revision: pci revision id
1344 * @prod_name: string returned
1346 * Returns product string displayed when driver loads,
1347 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1351 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1353 char *product_str = NULL;
1355 if (vendor == PCI_VENDOR_ID_BROCADE) {
1358 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1362 product_str = "BRE040 A0";
1365 product_str = "BRE040 A1";
1368 product_str = "BRE040";
1378 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1379 product_str = "LSIFC909 B1";
1381 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1382 product_str = "LSIFC919 B0";
1384 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1385 product_str = "LSIFC929 B0";
1387 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1388 if (revision < 0x80)
1389 product_str = "LSIFC919X A0";
1391 product_str = "LSIFC919XL A1";
1393 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1394 if (revision < 0x80)
1395 product_str = "LSIFC929X A0";
1397 product_str = "LSIFC929XL A1";
1399 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1400 product_str = "LSIFC939X A1";
1402 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1403 product_str = "LSIFC949X A1";
1405 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1409 product_str = "LSIFC949E A0";
1412 product_str = "LSIFC949E A1";
1415 product_str = "LSIFC949E";
1419 case MPI_MANUFACTPAGE_DEVID_53C1030:
1423 product_str = "LSI53C1030 A0";
1426 product_str = "LSI53C1030 B0";
1429 product_str = "LSI53C1030 B1";
1432 product_str = "LSI53C1030 B2";
1435 product_str = "LSI53C1030 C0";
1438 product_str = "LSI53C1030T A0";
1441 product_str = "LSI53C1030T A2";
1444 product_str = "LSI53C1030T A3";
1447 product_str = "LSI53C1020A A1";
1450 product_str = "LSI53C1030";
1454 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1458 product_str = "LSI53C1035 A2";
1461 product_str = "LSI53C1035 B0";
1464 product_str = "LSI53C1035";
1468 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1472 product_str = "LSISAS1064 A1";
1475 product_str = "LSISAS1064 A2";
1478 product_str = "LSISAS1064 A3";
1481 product_str = "LSISAS1064 A4";
1484 product_str = "LSISAS1064";
1488 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1492 product_str = "LSISAS1064E A0";
1495 product_str = "LSISAS1064E B0";
1498 product_str = "LSISAS1064E B1";
1501 product_str = "LSISAS1064E B2";
1504 product_str = "LSISAS1064E B3";
1507 product_str = "LSISAS1064E";
1511 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1515 product_str = "LSISAS1068 A0";
1518 product_str = "LSISAS1068 B0";
1521 product_str = "LSISAS1068 B1";
1524 product_str = "LSISAS1068";
1528 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1532 product_str = "LSISAS1068E A0";
1535 product_str = "LSISAS1068E B0";
1538 product_str = "LSISAS1068E B1";
1541 product_str = "LSISAS1068E B2";
1544 product_str = "LSISAS1068E B3";
1547 product_str = "LSISAS1068E";
1551 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1555 product_str = "LSISAS1078 A0";
1558 product_str = "LSISAS1078 B0";
1561 product_str = "LSISAS1078 C0";
1564 product_str = "LSISAS1078 C1";
1567 product_str = "LSISAS1078 C2";
1570 product_str = "LSISAS1078";
1578 sprintf(prod_name, "%s", product_str);
1582 * mpt_mapresources - map in memory mapped io
1583 * @ioc: Pointer to pointer to IOC adapter
1587 mpt_mapresources(MPT_ADAPTER *ioc)
1591 resource_size_t mem_phys;
1597 struct pci_dev *pdev;
1600 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1601 if (pci_enable_device_mem(pdev)) {
1602 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1603 "failed\n", ioc->name);
1606 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1607 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1608 "MEM failed\n", ioc->name);
1612 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1614 if (sizeof(dma_addr_t) > 4) {
1615 const uint64_t required_mask = dma_get_required_mask
1617 if (required_mask > DMA_BIT_MASK(32)
1618 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1619 && !pci_set_consistent_dma_mask(pdev,
1620 DMA_BIT_MASK(64))) {
1621 ioc->dma_mask = DMA_BIT_MASK(64);
1622 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1623 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1625 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1626 && !pci_set_consistent_dma_mask(pdev,
1627 DMA_BIT_MASK(32))) {
1628 ioc->dma_mask = DMA_BIT_MASK(32);
1629 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1630 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1633 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1634 ioc->name, pci_name(pdev));
1635 pci_release_selected_regions(pdev, ioc->bars);
1639 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1640 && !pci_set_consistent_dma_mask(pdev,
1641 DMA_BIT_MASK(32))) {
1642 ioc->dma_mask = DMA_BIT_MASK(32);
1643 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1644 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1647 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1648 ioc->name, pci_name(pdev));
1649 pci_release_selected_regions(pdev, ioc->bars);
1654 mem_phys = msize = 0;
1656 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1657 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1660 /* Get I/O space! */
1661 port = pci_resource_start(pdev, ii);
1662 psize = pci_resource_len(pdev, ii);
1667 mem_phys = pci_resource_start(pdev, ii);
1668 msize = pci_resource_len(pdev, ii);
1671 ioc->mem_size = msize;
1674 /* Get logical ptr for PciMem0 space */
1675 /*mem = ioremap(mem_phys, msize);*/
1676 mem = ioremap(mem_phys, msize);
1678 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1679 " memory!\n", ioc->name);
1680 pci_release_selected_regions(pdev, ioc->bars);
1684 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1685 ioc->name, mem, (unsigned long long)mem_phys));
1687 ioc->mem_phys = mem_phys;
1688 ioc->chip = (SYSIF_REGS __iomem *)mem;
1690 /* Save Port IO values in case we need to do downloadboot */
1691 ioc->pio_mem_phys = port;
1692 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1697 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1699 * mpt_attach - Install a PCI intelligent MPT adapter.
1700 * @pdev: Pointer to pci_dev structure
1701 * @id: PCI device ID information
1703 * This routine performs all the steps necessary to bring the IOC of
1704 * a MPT adapter to a OPERATIONAL state. This includes registering
1705 * memory regions, registering the interrupt, and allocating request
1706 * and reply memory pools.
1708 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1711 * Returns 0 for success, non-zero for failure.
1713 * TODO: Add support for polled controllers
1716 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1723 static int mpt_ids = 0;
1724 #ifdef CONFIG_PROC_FS
1725 struct proc_dir_entry *dent;
1728 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1730 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1734 ioc->id = mpt_ids++;
1735 sprintf(ioc->name, "ioc%d", ioc->id);
1736 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1739 * set initial debug level
1740 * (refer to mptdebug.h)
1743 ioc->debug_level = mpt_debug_level;
1744 if (mpt_debug_level)
1745 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1747 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1750 if (mpt_mapresources(ioc)) {
1756 * Setting up proper handlers for scatter gather handling
1758 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1759 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1760 ioc->add_sge = &mpt_add_sge_64bit_1078;
1762 ioc->add_sge = &mpt_add_sge_64bit;
1763 ioc->add_chain = &mpt_add_chain_64bit;
1764 ioc->sg_addr_size = 8;
1766 ioc->add_sge = &mpt_add_sge;
1767 ioc->add_chain = &mpt_add_chain;
1768 ioc->sg_addr_size = 4;
1770 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1772 ioc->alloc_total = sizeof(MPT_ADAPTER);
1773 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1774 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1777 spin_lock_init(&ioc->taskmgmt_lock);
1778 mutex_init(&ioc->internal_cmds.mutex);
1779 init_completion(&ioc->internal_cmds.done);
1780 mutex_init(&ioc->mptbase_cmds.mutex);
1781 init_completion(&ioc->mptbase_cmds.done);
1782 mutex_init(&ioc->taskmgmt_cmds.mutex);
1783 init_completion(&ioc->taskmgmt_cmds.done);
1785 /* Initialize the event logging.
1787 ioc->eventTypes = 0; /* None */
1788 ioc->eventContext = 0;
1789 ioc->eventLogSize = 0;
1797 ioc->cached_fw = NULL;
1799 /* Initialize SCSI Config Data structure
1801 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1803 /* Initialize the fc rport list head.
1805 INIT_LIST_HEAD(&ioc->fc_rports);
1807 /* Find lookup slot. */
1808 INIT_LIST_HEAD(&ioc->list);
1811 /* Initialize workqueue */
1812 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1814 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1815 "mpt_poll_%d", ioc->id);
1817 create_singlethread_workqueue(ioc->reset_work_q_name);
1818 if (!ioc->reset_work_q) {
1819 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1821 pci_release_selected_regions(pdev, ioc->bars);
1826 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1827 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1829 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1830 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1832 switch (pdev->device)
1834 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1835 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1836 ioc->errata_flag_1064 = 1;
1837 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1838 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1839 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1840 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1844 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1845 if (revision < XL_929) {
1846 /* 929X Chip Fix. Set Split transactions level
1847 * for PCIX. Set MOST bits to zero.
1849 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1851 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1853 /* 929XL Chip Fix. Set MMRBC to 0x08.
1855 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1857 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1862 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1863 /* 919X 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);
1872 case MPI_MANUFACTPAGE_DEVID_53C1030:
1873 /* 1030 Chip Fix. Disable Split transactions
1874 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1876 if (revision < C0_1030) {
1877 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1879 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1882 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1883 ioc->bus_type = SPI;
1886 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1887 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1888 ioc->errata_flag_1064 = 1;
1889 ioc->bus_type = SAS;
1892 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1893 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1894 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1895 ioc->bus_type = SAS;
1900 switch (ioc->bus_type) {
1903 ioc->msi_enable = mpt_msi_enable_sas;
1907 ioc->msi_enable = mpt_msi_enable_spi;
1911 ioc->msi_enable = mpt_msi_enable_fc;
1915 ioc->msi_enable = 0;
1919 ioc->fw_events_off = 1;
1921 if (ioc->errata_flag_1064)
1922 pci_disable_io_access(pdev);
1924 spin_lock_init(&ioc->FreeQlock);
1927 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1929 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1931 /* Set IOC ptr in the pcidev's driver data. */
1932 pci_set_drvdata(ioc->pcidev, ioc);
1934 /* Set lookup ptr. */
1935 list_add_tail(&ioc->list, &ioc_list);
1937 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1939 mpt_detect_bound_ports(ioc, pdev);
1941 INIT_LIST_HEAD(&ioc->fw_event_list);
1942 spin_lock_init(&ioc->fw_event_lock);
1943 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1944 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1946 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1948 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1951 list_del(&ioc->list);
1953 ioc->alt_ioc->alt_ioc = NULL;
1954 iounmap(ioc->memmap);
1956 pci_release_selected_regions(pdev, ioc->bars);
1958 destroy_workqueue(ioc->reset_work_q);
1959 ioc->reset_work_q = NULL;
1962 pci_set_drvdata(pdev, NULL);
1966 /* call per device driver probe entry point */
1967 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1968 if(MptDeviceDriverHandlers[cb_idx] &&
1969 MptDeviceDriverHandlers[cb_idx]->probe) {
1970 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1974 #ifdef CONFIG_PROC_FS
1976 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1978 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1980 proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc);
1981 proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc);
1986 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1987 msecs_to_jiffies(MPT_POLLING_INTERVAL));
1992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1994 * mpt_detach - Remove a PCI intelligent MPT adapter.
1995 * @pdev: Pointer to pci_dev structure
1999 mpt_detach(struct pci_dev *pdev)
2001 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2004 unsigned long flags;
2005 struct workqueue_struct *wq;
2008 * Stop polling ioc for fault condition
2010 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2011 wq = ioc->reset_work_q;
2012 ioc->reset_work_q = NULL;
2013 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2014 cancel_delayed_work(&ioc->fault_reset_work);
2015 destroy_workqueue(wq);
2017 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2018 wq = ioc->fw_event_q;
2019 ioc->fw_event_q = NULL;
2020 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2021 destroy_workqueue(wq);
2023 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2024 remove_proc_entry(pname, NULL);
2025 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2026 remove_proc_entry(pname, NULL);
2027 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2028 remove_proc_entry(pname, NULL);
2030 /* call per device driver remove entry point */
2031 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2032 if(MptDeviceDriverHandlers[cb_idx] &&
2033 MptDeviceDriverHandlers[cb_idx]->remove) {
2034 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2038 /* Disable interrupts! */
2039 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2042 synchronize_irq(pdev->irq);
2044 /* Clear any lingering interrupt */
2045 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2047 CHIPREG_READ32(&ioc->chip->IntStatus);
2049 mpt_adapter_dispose(ioc);
2053 /**************************************************************************
2057 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2059 * mpt_suspend - Fusion MPT base driver suspend routine.
2060 * @pdev: Pointer to pci_dev structure
2061 * @state: new state to enter
2064 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2067 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2069 device_state = pci_choose_state(pdev, state);
2070 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2071 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2074 /* put ioc into READY_STATE */
2075 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2076 printk(MYIOC_s_ERR_FMT
2077 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2080 /* disable interrupts */
2081 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2084 /* Clear any lingering interrupt */
2085 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2087 free_irq(ioc->pci_irq, ioc);
2088 if (ioc->msi_enable)
2089 pci_disable_msi(ioc->pcidev);
2091 pci_save_state(pdev);
2092 pci_disable_device(pdev);
2093 pci_release_selected_regions(pdev, ioc->bars);
2094 pci_set_power_state(pdev, device_state);
2098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2100 * mpt_resume - Fusion MPT base driver resume routine.
2101 * @pdev: Pointer to pci_dev structure
2104 mpt_resume(struct pci_dev *pdev)
2106 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2107 u32 device_state = pdev->current_state;
2111 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2112 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2115 pci_set_power_state(pdev, PCI_D0);
2116 pci_enable_wake(pdev, PCI_D0, 0);
2117 pci_restore_state(pdev);
2119 err = mpt_mapresources(ioc);
2123 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2124 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2125 ioc->add_sge = &mpt_add_sge_64bit_1078;
2127 ioc->add_sge = &mpt_add_sge_64bit;
2128 ioc->add_chain = &mpt_add_chain_64bit;
2129 ioc->sg_addr_size = 8;
2132 ioc->add_sge = &mpt_add_sge;
2133 ioc->add_chain = &mpt_add_chain;
2134 ioc->sg_addr_size = 4;
2136 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2138 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2139 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2140 CHIPREG_READ32(&ioc->chip->Doorbell));
2143 * Errata workaround for SAS pci express:
2144 * Upon returning to the D0 state, the contents of the doorbell will be
2145 * stale data, and this will incorrectly signal to the host driver that
2146 * the firmware is ready to process mpt commands. The workaround is
2147 * to issue a diagnostic reset.
2149 if (ioc->bus_type == SAS && (pdev->device ==
2150 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2151 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2152 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2153 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2159 /* bring ioc to operational state */
2160 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2161 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2163 if (recovery_state != 0)
2164 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2165 "error:[%x]\n", ioc->name, recovery_state);
2167 printk(MYIOC_s_INFO_FMT
2168 "pci-resume: success\n", ioc->name);
2176 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2178 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2179 ioc->bus_type != SPI) ||
2180 (MptDriverClass[index] == MPTFC_DRIVER &&
2181 ioc->bus_type != FC) ||
2182 (MptDriverClass[index] == MPTSAS_DRIVER &&
2183 ioc->bus_type != SAS))
2184 /* make sure we only call the relevant reset handler
2187 return (MptResetHandlers[index])(ioc, reset_phase);
2190 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2192 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2193 * @ioc: Pointer to MPT adapter structure
2194 * @reason: Event word / reason
2195 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2197 * This routine performs all the steps necessary to bring the IOC
2198 * to a OPERATIONAL state.
2200 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2205 * -1 if failed to get board READY
2206 * -2 if READY but IOCFacts Failed
2207 * -3 if READY but PrimeIOCFifos Failed
2208 * -4 if READY but IOCInit Failed
2209 * -5 if failed to enable_device and/or request_selected_regions
2210 * -6 if failed to upload firmware
2213 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2215 int hard_reset_done = 0;
2216 int alt_ioc_ready = 0;
2221 int reset_alt_ioc_active = 0;
2222 int irq_allocated = 0;
2225 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2226 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2228 /* Disable reply interrupts (also blocks FreeQ) */
2229 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2233 if (ioc->alt_ioc->active ||
2234 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2235 reset_alt_ioc_active = 1;
2236 /* Disable alt-IOC's reply interrupts
2237 * (and FreeQ) for a bit
2239 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2241 ioc->alt_ioc->active = 0;
2246 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2249 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2250 if (hard_reset_done == -4) {
2251 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2254 if (reset_alt_ioc_active && ioc->alt_ioc) {
2255 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2256 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2257 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2258 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2259 ioc->alt_ioc->active = 1;
2263 printk(MYIOC_s_WARN_FMT
2264 "NOT READY WARNING!\n", ioc->name);
2270 /* hard_reset_done = 0 if a soft reset was performed
2271 * and 1 if a hard reset was performed.
2273 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2274 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2277 printk(MYIOC_s_WARN_FMT
2278 ": alt-ioc Not ready WARNING!\n",
2279 ioc->alt_ioc->name);
2282 for (ii=0; ii<5; ii++) {
2283 /* Get IOC facts! Allow 5 retries */
2284 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2290 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2291 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2293 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2294 MptDisplayIocCapabilities(ioc);
2297 if (alt_ioc_ready) {
2298 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2299 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2300 "Initial Alt IocFacts failed rc=%x\n",
2302 /* Retry - alt IOC was initialized once
2304 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2307 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2308 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2310 reset_alt_ioc_active = 0;
2311 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2312 MptDisplayIocCapabilities(ioc->alt_ioc);
2316 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2317 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2318 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2319 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2321 if (pci_enable_device(ioc->pcidev))
2323 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2329 * Device is reset now. It must have de-asserted the interrupt line
2330 * (if it was asserted) and it should be safe to register for the
2333 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2335 if (ioc->pcidev->irq) {
2336 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2337 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2340 ioc->msi_enable = 0;
2341 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2342 IRQF_SHARED, ioc->name, ioc);
2344 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2346 ioc->name, ioc->pcidev->irq);
2347 if (ioc->msi_enable)
2348 pci_disable_msi(ioc->pcidev);
2353 ioc->pci_irq = ioc->pcidev->irq;
2354 pci_set_master(ioc->pcidev); /* ?? */
2355 pci_set_drvdata(ioc->pcidev, ioc);
2356 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2357 "installed at interrupt %d\n", ioc->name,
2362 /* Prime reply & request queues!
2363 * (mucho alloc's) Must be done prior to
2364 * init as upper addresses are needed for init.
2365 * If fails, continue with alt-ioc processing
2367 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2369 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2372 /* May need to check/upload firmware & data here!
2373 * If fails, continue with alt-ioc processing
2375 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2377 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2380 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2381 printk(MYIOC_s_WARN_FMT
2382 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2383 ioc->alt_ioc->name, rc);
2385 reset_alt_ioc_active = 0;
2388 if (alt_ioc_ready) {
2389 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2391 reset_alt_ioc_active = 0;
2392 printk(MYIOC_s_WARN_FMT
2393 ": alt-ioc: (%d) init failure WARNING!\n",
2394 ioc->alt_ioc->name, rc);
2398 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2399 if (ioc->upload_fw) {
2400 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2401 "firmware upload required!\n", ioc->name));
2403 /* Controller is not operational, cannot do upload
2406 rc = mpt_do_upload(ioc, sleepFlag);
2408 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2410 * Maintain only one pointer to FW memory
2411 * so there will not be two attempt to
2412 * downloadboot onboard dual function
2413 * chips (mpt_adapter_disable,
2416 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2417 "mpt_upload: alt_%s has cached_fw=%p \n",
2418 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2419 ioc->cached_fw = NULL;
2422 printk(MYIOC_s_WARN_FMT
2423 "firmware upload failure!\n", ioc->name);
2430 /* Enable MPT base driver management of EventNotification
2431 * and EventAck handling.
2433 if ((ret == 0) && (!ioc->facts.EventState)) {
2434 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2435 "SendEventNotification\n",
2437 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2440 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2441 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2444 /* Enable! (reply interrupt) */
2445 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2448 if (rc == 0) { /* alt ioc */
2449 if (reset_alt_ioc_active && ioc->alt_ioc) {
2450 /* (re)Enable alt-IOC! (reply interrupt) */
2451 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2452 "reply irq re-enabled\n",
2453 ioc->alt_ioc->name));
2454 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2456 ioc->alt_ioc->active = 1;
2461 /* Add additional "reason" check before call to GetLanConfigPages
2462 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2463 * recursive scenario; GetLanConfigPages times out, timer expired
2464 * routine calls HardResetHandler, which calls into here again,
2465 * and we try GetLanConfigPages again...
2467 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2470 * Initialize link list for inactive raid volumes.
2472 mutex_init(&ioc->raid_data.inactive_list_mutex);
2473 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2475 switch (ioc->bus_type) {
2478 /* clear persistency table */
2479 if(ioc->facts.IOCExceptions &
2480 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2481 ret = mptbase_sas_persist_operation(ioc,
2482 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2489 mpt_findImVolumes(ioc);
2491 /* Check, and possibly reset, the coalescing value
2493 mpt_read_ioc_pg_1(ioc);
2498 if ((ioc->pfacts[0].ProtocolFlags &
2499 MPI_PORTFACTS_PROTOCOL_LAN) &&
2500 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2502 * Pre-fetch the ports LAN MAC address!
2503 * (LANPage1_t stuff)
2505 (void) GetLanConfigPages(ioc);
2506 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2507 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2508 "LanAddr = %02X:%02X:%02X"
2509 ":%02X:%02X:%02X\n",
2510 ioc->name, a[5], a[4],
2511 a[3], a[2], a[1], a[0]));
2516 /* Get NVRAM and adapter maximums from SPP 0 and 2
2518 mpt_GetScsiPortSettings(ioc, 0);
2520 /* Get version and length of SDP 1
2522 mpt_readScsiDevicePageHeaders(ioc, 0);
2526 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2527 mpt_findImVolumes(ioc);
2529 /* Check, and possibly reset, the coalescing value
2531 mpt_read_ioc_pg_1(ioc);
2533 mpt_read_ioc_pg_4(ioc);
2538 GetIoUnitPage2(ioc);
2539 mpt_get_manufacturing_pg_0(ioc);
2543 if ((ret != 0) && irq_allocated) {
2544 free_irq(ioc->pci_irq, ioc);
2545 if (ioc->msi_enable)
2546 pci_disable_msi(ioc->pcidev);
2551 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2553 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2554 * @ioc: Pointer to MPT adapter structure
2555 * @pdev: Pointer to (struct pci_dev) structure
2557 * Search for PCI bus/dev_function which matches
2558 * PCI bus/dev_function (+/-1) for newly discovered 929,
2559 * 929X, 1030 or 1035.
2561 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2562 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2565 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2567 struct pci_dev *peer=NULL;
2568 unsigned int slot = PCI_SLOT(pdev->devfn);
2569 unsigned int func = PCI_FUNC(pdev->devfn);
2570 MPT_ADAPTER *ioc_srch;
2572 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2573 " searching for devfn match on %x or %x\n",
2574 ioc->name, pci_name(pdev), pdev->bus->number,
2575 pdev->devfn, func-1, func+1));
2577 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2579 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2584 list_for_each_entry(ioc_srch, &ioc_list, list) {
2585 struct pci_dev *_pcidev = ioc_srch->pcidev;
2586 if (_pcidev == peer) {
2587 /* Paranoia checks */
2588 if (ioc->alt_ioc != NULL) {
2589 printk(MYIOC_s_WARN_FMT
2590 "Oops, already bound (%s <==> %s)!\n",
2591 ioc->name, ioc->name, ioc->alt_ioc->name);
2593 } else if (ioc_srch->alt_ioc != NULL) {
2594 printk(MYIOC_s_WARN_FMT
2595 "Oops, already bound (%s <==> %s)!\n",
2596 ioc_srch->name, ioc_srch->name,
2597 ioc_srch->alt_ioc->name);
2600 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2601 "FOUND! binding %s <==> %s\n",
2602 ioc->name, ioc->name, ioc_srch->name));
2603 ioc_srch->alt_ioc = ioc;
2604 ioc->alt_ioc = ioc_srch;
2610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2612 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2613 * @ioc: Pointer to MPT adapter structure
2616 mpt_adapter_disable(MPT_ADAPTER *ioc)
2621 if (ioc->cached_fw != NULL) {
2622 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2623 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2624 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2625 ioc->cached_fw, CAN_SLEEP)) < 0) {
2626 printk(MYIOC_s_WARN_FMT
2627 ": firmware downloadboot failure (%d)!\n",
2633 * Put the controller into ready state (if its not already)
2635 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2636 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2638 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2639 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2640 "reset failed to put ioc in ready state!\n",
2641 ioc->name, __func__);
2643 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2644 "failed!\n", ioc->name, __func__);
2648 /* Disable adapter interrupts! */
2649 synchronize_irq(ioc->pcidev->irq);
2650 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2653 /* Clear any lingering interrupt */
2654 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2655 CHIPREG_READ32(&ioc->chip->IntStatus);
2657 if (ioc->alloc != NULL) {
2659 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2660 ioc->name, ioc->alloc, ioc->alloc_sz));
2661 pci_free_consistent(ioc->pcidev, sz,
2662 ioc->alloc, ioc->alloc_dma);
2663 ioc->reply_frames = NULL;
2664 ioc->req_frames = NULL;
2666 ioc->alloc_total -= sz;
2669 if (ioc->sense_buf_pool != NULL) {
2670 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2671 pci_free_consistent(ioc->pcidev, sz,
2672 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2673 ioc->sense_buf_pool = NULL;
2674 ioc->alloc_total -= sz;
2677 if (ioc->events != NULL){
2678 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2681 ioc->alloc_total -= sz;
2684 mpt_free_fw_memory(ioc);
2686 kfree(ioc->spi_data.nvram);
2687 mpt_inactive_raid_list_free(ioc);
2688 kfree(ioc->raid_data.pIocPg2);
2689 kfree(ioc->raid_data.pIocPg3);
2690 ioc->spi_data.nvram = NULL;
2691 ioc->raid_data.pIocPg3 = NULL;
2693 if (ioc->spi_data.pIocPg4 != NULL) {
2694 sz = ioc->spi_data.IocPg4Sz;
2695 pci_free_consistent(ioc->pcidev, sz,
2696 ioc->spi_data.pIocPg4,
2697 ioc->spi_data.IocPg4_dma);
2698 ioc->spi_data.pIocPg4 = NULL;
2699 ioc->alloc_total -= sz;
2702 if (ioc->ReqToChain != NULL) {
2703 kfree(ioc->ReqToChain);
2704 kfree(ioc->RequestNB);
2705 ioc->ReqToChain = NULL;
2708 kfree(ioc->ChainToChain);
2709 ioc->ChainToChain = NULL;
2711 if (ioc->HostPageBuffer != NULL) {
2712 if((ret = mpt_host_page_access_control(ioc,
2713 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2714 printk(MYIOC_s_ERR_FMT
2715 ": %s: host page buffers free failed (%d)!\n",
2716 ioc->name, __func__, ret);
2718 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2719 "HostPageBuffer free @ %p, sz=%d bytes\n",
2720 ioc->name, ioc->HostPageBuffer,
2721 ioc->HostPageBuffer_sz));
2722 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2723 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2724 ioc->HostPageBuffer = NULL;
2725 ioc->HostPageBuffer_sz = 0;
2726 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2729 pci_set_drvdata(ioc->pcidev, NULL);
2731 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2733 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2734 * @ioc: Pointer to MPT adapter structure
2736 * This routine unregisters h/w resources and frees all alloc'd memory
2737 * associated with a MPT adapter structure.
2740 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2742 int sz_first, sz_last;
2747 sz_first = ioc->alloc_total;
2749 mpt_adapter_disable(ioc);
2751 if (ioc->pci_irq != -1) {
2752 free_irq(ioc->pci_irq, ioc);
2753 if (ioc->msi_enable)
2754 pci_disable_msi(ioc->pcidev);
2758 if (ioc->memmap != NULL) {
2759 iounmap(ioc->memmap);
2763 pci_disable_device(ioc->pcidev);
2764 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2766 #if defined(CONFIG_MTRR) && 0
2767 if (ioc->mtrr_reg > 0) {
2768 mtrr_del(ioc->mtrr_reg, 0, 0);
2769 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2773 /* Zap the adapter lookup ptr! */
2774 list_del(&ioc->list);
2776 sz_last = ioc->alloc_total;
2777 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2778 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2781 ioc->alt_ioc->alt_ioc = NULL;
2786 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2788 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2789 * @ioc: Pointer to MPT adapter structure
2792 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2796 printk(KERN_INFO "%s: ", ioc->name);
2798 printk("%s: ", ioc->prod_name);
2799 printk("Capabilities={");
2801 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2802 printk("Initiator");
2806 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2807 printk("%sTarget", i ? "," : "");
2811 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2812 printk("%sLAN", i ? "," : "");
2818 * This would probably evoke more questions than it's worth
2820 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2821 printk("%sLogBusAddr", i ? "," : "");
2829 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2831 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2832 * @ioc: Pointer to MPT_ADAPTER structure
2833 * @force: Force hard KickStart of IOC
2834 * @sleepFlag: Specifies whether the process can sleep
2837 * 1 - DIAG reset and READY
2838 * 0 - READY initially OR soft reset and READY
2839 * -1 - Any failure on KickStart
2840 * -2 - Msg Unit Reset Failed
2841 * -3 - IO Unit Reset Failed
2842 * -4 - IOC owned by a PEER
2845 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2850 int hard_reset_done = 0;
2855 /* Get current [raw] IOC state */
2856 ioc_state = mpt_GetIocState(ioc, 0);
2857 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2860 * Check to see if IOC got left/stuck in doorbell handshake
2861 * grip of death. If so, hard reset the IOC.
2863 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2865 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2869 /* Is it already READY? */
2871 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2872 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2873 "IOC is in READY state\n", ioc->name));
2878 * Check to see if IOC is in FAULT state.
2880 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2882 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2884 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2885 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2889 * Hmmm... Did it get left operational?
2891 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2892 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2896 * If PCI Peer, exit.
2897 * Else, if no fault conditions are present, issue a MessageUnitReset
2898 * Else, fall through to KickStart case
2900 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2901 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2902 "whoinit 0x%x statefault %d force %d\n",
2903 ioc->name, whoinit, statefault, force));
2904 if (whoinit == MPI_WHOINIT_PCI_PEER)
2907 if ((statefault == 0 ) && (force == 0)) {
2908 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2915 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2916 if (hard_reset_done < 0)
2920 * Loop here waiting for IOC to come READY.
2923 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2925 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2926 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2928 * BIOS or previous driver load left IOC in OP state.
2929 * Reset messaging FIFOs.
2931 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2932 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2935 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2937 * Something is wrong. Try to get IOC back
2940 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2941 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2948 printk(MYIOC_s_ERR_FMT
2949 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2950 ioc->name, ioc_state, (int)((ii+5)/HZ));
2954 if (sleepFlag == CAN_SLEEP) {
2957 mdelay (1); /* 1 msec delay */
2962 if (statefault < 3) {
2963 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
2964 statefault == 1 ? "stuck handshake" : "IOC FAULT");
2967 return hard_reset_done;
2970 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2972 * mpt_GetIocState - Get the current state of a MPT adapter.
2973 * @ioc: Pointer to MPT_ADAPTER structure
2974 * @cooked: Request raw or cooked IOC state
2976 * Returns all IOC Doorbell register bits if cooked==0, else just the
2977 * Doorbell bits in MPI_IOC_STATE_MASK.
2980 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2985 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2986 sc = s & MPI_IOC_STATE_MASK;
2989 ioc->last_state = sc;
2991 return cooked ? sc : s;
2994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2996 * GetIocFacts - Send IOCFacts request to MPT adapter.
2997 * @ioc: Pointer to MPT_ADAPTER structure
2998 * @sleepFlag: Specifies whether the process can sleep
2999 * @reason: If recovery, only update facts.
3001 * Returns 0 for success, non-zero for failure.
3004 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3006 IOCFacts_t get_facts;
3007 IOCFactsReply_t *facts;
3015 /* IOC *must* NOT be in RESET state! */
3016 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3017 printk(KERN_ERR MYNAM
3018 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3019 ioc->name, ioc->last_state);
3023 facts = &ioc->facts;
3025 /* Destination (reply area)... */
3026 reply_sz = sizeof(*facts);
3027 memset(facts, 0, reply_sz);
3029 /* Request area (get_facts on the stack right now!) */
3030 req_sz = sizeof(get_facts);
3031 memset(&get_facts, 0, req_sz);
3033 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3034 /* Assert: All other get_facts fields are zero! */
3036 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3037 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3038 ioc->name, req_sz, reply_sz));
3040 /* No non-zero fields in the get_facts request are greater than
3041 * 1 byte in size, so we can just fire it off as is.
3043 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3044 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3049 * Now byte swap (GRRR) the necessary fields before any further
3050 * inspection of reply contents.
3052 * But need to do some sanity checks on MsgLength (byte) field
3053 * to make sure we don't zero IOC's req_sz!
3055 /* Did we get a valid reply? */
3056 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3057 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3059 * If not been here, done that, save off first WhoInit value
3061 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3062 ioc->FirstWhoInit = facts->WhoInit;
3065 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3066 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3067 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3068 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3069 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3070 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3071 /* CHECKME! IOCStatus, IOCLogInfo */
3073 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3074 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3077 * FC f/w version changed between 1.1 and 1.2
3078 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3079 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3081 if (facts->MsgVersion < MPI_VERSION_01_02) {
3083 * Handle old FC f/w style, convert to new...
3085 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3086 facts->FWVersion.Word =
3087 ((oldv<<12) & 0xFF000000) |
3088 ((oldv<<8) & 0x000FFF00);
3090 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3092 facts->ProductID = le16_to_cpu(facts->ProductID);
3094 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3095 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3096 ioc->ir_firmware = 1;
3098 facts->CurrentHostMfaHighAddr =
3099 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3100 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3101 facts->CurrentSenseBufferHighAddr =
3102 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3103 facts->CurReplyFrameSize =
3104 le16_to_cpu(facts->CurReplyFrameSize);
3105 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3108 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3109 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3110 * to 14 in MPI-1.01.0x.
3112 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3113 facts->MsgVersion > MPI_VERSION_01_00) {
3114 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3117 sz = facts->FWImageSize;
3122 facts->FWImageSize = sz;
3124 if (!facts->RequestFrameSize) {
3125 /* Something is wrong! */
3126 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3131 r = sz = facts->BlockSize;
3132 vv = ((63 / (sz * 4)) + 1) & 0x03;
3133 ioc->NB_for_64_byte_frame = vv;
3139 ioc->NBShiftFactor = shiftFactor;
3140 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3141 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3142 ioc->name, vv, shiftFactor, r));
3144 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3146 * Set values for this IOC's request & reply frame sizes,
3147 * and request & reply queue depths...
3149 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3150 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3151 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3152 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3154 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3155 ioc->name, ioc->reply_sz, ioc->reply_depth));
3156 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3157 ioc->name, ioc->req_sz, ioc->req_depth));
3159 /* Get port facts! */
3160 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3164 printk(MYIOC_s_ERR_FMT
3165 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3166 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3167 RequestFrameSize)/sizeof(u32)));
3174 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3176 * GetPortFacts - Send PortFacts request to MPT adapter.
3177 * @ioc: Pointer to MPT_ADAPTER structure
3178 * @portnum: Port number
3179 * @sleepFlag: Specifies whether the process can sleep
3181 * Returns 0 for success, non-zero for failure.
3184 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3186 PortFacts_t get_pfacts;
3187 PortFactsReply_t *pfacts;
3193 /* IOC *must* NOT be in RESET state! */
3194 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3195 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3196 ioc->name, ioc->last_state );
3200 pfacts = &ioc->pfacts[portnum];
3202 /* Destination (reply area)... */
3203 reply_sz = sizeof(*pfacts);
3204 memset(pfacts, 0, reply_sz);
3206 /* Request area (get_pfacts on the stack right now!) */
3207 req_sz = sizeof(get_pfacts);
3208 memset(&get_pfacts, 0, req_sz);
3210 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3211 get_pfacts.PortNumber = portnum;
3212 /* Assert: All other get_pfacts fields are zero! */
3214 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3215 ioc->name, portnum));
3217 /* No non-zero fields in the get_pfacts request are greater than
3218 * 1 byte in size, so we can just fire it off as is.
3220 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3221 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3225 /* Did we get a valid reply? */
3227 /* Now byte swap the necessary fields in the response. */
3228 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3229 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3230 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3231 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3232 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3233 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3234 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3235 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3236 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3238 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3240 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3241 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3244 * Place all the devices on channels
3248 if (mpt_channel_mapping) {
3249 ioc->devices_per_bus = 1;
3250 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3256 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3258 * SendIocInit - Send IOCInit request to MPT adapter.
3259 * @ioc: Pointer to MPT_ADAPTER structure
3260 * @sleepFlag: Specifies whether the process can sleep
3262 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3264 * Returns 0 for success, non-zero for failure.
3267 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3270 MPIDefaultReply_t init_reply;
3276 memset(&ioc_init, 0, sizeof(ioc_init));
3277 memset(&init_reply, 0, sizeof(init_reply));
3279 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3280 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3282 /* If we are in a recovery mode and we uploaded the FW image,
3283 * then this pointer is not NULL. Skip the upload a second time.
3284 * Set this flag if cached_fw set for either IOC.
3286 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3290 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3291 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3293 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3294 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3296 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3297 ioc->name, ioc->facts.MsgVersion));
3298 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3299 // set MsgVersion and HeaderVersion host driver was built with
3300 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3301 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3303 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3304 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3305 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3308 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3310 if (ioc->sg_addr_size == sizeof(u64)) {
3311 /* Save the upper 32-bits of the request
3312 * (reply) and sense buffers.
3314 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3315 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3317 /* Force 32-bit addressing */
3318 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3319 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3322 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3323 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3324 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3325 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3327 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3328 ioc->name, &ioc_init));
3330 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3331 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3333 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3337 /* No need to byte swap the multibyte fields in the reply
3338 * since we don't even look at its contents.
3341 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3342 ioc->name, &ioc_init));
3344 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3345 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3349 /* YIKES! SUPER IMPORTANT!!!
3350 * Poll IocState until _OPERATIONAL while IOC is doing
3351 * LoopInit and TargetDiscovery!
3354 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3355 state = mpt_GetIocState(ioc, 1);
3356 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3357 if (sleepFlag == CAN_SLEEP) {
3364 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3365 ioc->name, (int)((count+5)/HZ));
3369 state = mpt_GetIocState(ioc, 1);
3372 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3375 ioc->aen_event_read_flag=0;
3379 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3381 * SendPortEnable - Send PortEnable request to MPT adapter port.
3382 * @ioc: Pointer to MPT_ADAPTER structure
3383 * @portnum: Port number to enable
3384 * @sleepFlag: Specifies whether the process can sleep
3386 * Send PortEnable to bring IOC to OPERATIONAL state.
3388 * Returns 0 for success, non-zero for failure.
3391 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3393 PortEnable_t port_enable;
3394 MPIDefaultReply_t reply_buf;
3399 /* Destination... */
3400 reply_sz = sizeof(MPIDefaultReply_t);
3401 memset(&reply_buf, 0, reply_sz);
3403 req_sz = sizeof(PortEnable_t);
3404 memset(&port_enable, 0, req_sz);
3406 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3407 port_enable.PortNumber = portnum;
3408 /* port_enable.ChainOffset = 0; */
3409 /* port_enable.MsgFlags = 0; */
3410 /* port_enable.MsgContext = 0; */
3412 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3413 ioc->name, portnum, &port_enable));
3415 /* RAID FW may take a long time to enable
3417 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3418 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3419 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3420 300 /*seconds*/, sleepFlag);
3422 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3423 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3424 30 /*seconds*/, sleepFlag);
3430 * mpt_alloc_fw_memory - allocate firmware memory
3431 * @ioc: Pointer to MPT_ADAPTER structure
3432 * @size: total FW bytes
3434 * If memory has already been allocated, the same (cached) value
3437 * Return 0 if successfull, or non-zero for failure
3440 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3444 if (ioc->cached_fw) {
3445 rc = 0; /* use already allocated memory */
3448 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3449 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3450 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3454 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3455 if (!ioc->cached_fw) {
3456 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3460 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3461 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3462 ioc->alloc_total += size;
3470 * mpt_free_fw_memory - free firmware memory
3471 * @ioc: Pointer to MPT_ADAPTER structure
3473 * If alt_img is NULL, delete from ioc structure.
3474 * Else, delete a secondary image in same format.
3477 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3481 if (!ioc->cached_fw)
3484 sz = ioc->facts.FWImageSize;
3485 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3486 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3487 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3488 ioc->alloc_total -= sz;
3489 ioc->cached_fw = NULL;
3492 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3494 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3495 * @ioc: Pointer to MPT_ADAPTER structure
3496 * @sleepFlag: Specifies whether the process can sleep
3498 * Returns 0 for success, >0 for handshake failure
3499 * <0 for fw upload failure.
3501 * Remark: If bound IOC and a successful FWUpload was performed
3502 * on the bound IOC, the second image is discarded
3503 * and memory is free'd. Both channels must upload to prevent
3504 * IOC from running in degraded mode.
3507 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3509 u8 reply[sizeof(FWUploadReply_t)];
3510 FWUpload_t *prequest;
3511 FWUploadReply_t *preply;
3512 FWUploadTCSGE_t *ptcsge;
3514 int ii, sz, reply_sz;
3517 /* If the image size is 0, we are done.
3519 if ((sz = ioc->facts.FWImageSize) == 0)
3522 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3525 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3526 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3528 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3529 kzalloc(ioc->req_sz, GFP_KERNEL);
3531 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3532 "while allocating memory \n", ioc->name));
3533 mpt_free_fw_memory(ioc);
3537 preply = (FWUploadReply_t *)&reply;
3539 reply_sz = sizeof(reply);
3540 memset(preply, 0, reply_sz);
3542 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3543 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3545 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3546 ptcsge->DetailsLength = 12;
3547 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3548 ptcsge->ImageSize = cpu_to_le32(sz);
3551 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3552 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3553 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3555 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3556 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3557 ioc->facts.FWImageSize, request_size));
3558 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3560 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3561 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3563 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3564 "rc=%x \n", ioc->name, ii));
3566 cmdStatus = -EFAULT;
3568 /* Handshake transfer was complete and successful.
3569 * Check the Reply Frame.
3572 status = le16_to_cpu(preply->IOCStatus) &
3574 if (status == MPI_IOCSTATUS_SUCCESS &&
3575 ioc->facts.FWImageSize ==
3576 le32_to_cpu(preply->ActualImageSize))
3579 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3580 ioc->name, cmdStatus));
3584 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3585 "freeing image \n", ioc->name));
3586 mpt_free_fw_memory(ioc);
3593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3595 * mpt_downloadboot - DownloadBoot code
3596 * @ioc: Pointer to MPT_ADAPTER structure
3597 * @pFwHeader: Pointer to firmware header info
3598 * @sleepFlag: Specifies whether the process can sleep
3600 * FwDownloadBoot requires Programmed IO access.
3602 * Returns 0 for success
3603 * -1 FW Image size is 0
3604 * -2 No valid cached_fw Pointer
3605 * <0 for fw upload failure.
3608 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3610 MpiExtImageHeader_t *pExtImage;
3620 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3621 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3623 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3624 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3625 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3626 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3627 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3628 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3630 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3633 if (sleepFlag == CAN_SLEEP) {
3639 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3640 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3642 for (count = 0; count < 30; count ++) {
3643 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3644 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3645 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3650 if (sleepFlag == CAN_SLEEP) {
3657 if ( count == 30 ) {
3658 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3659 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3660 ioc->name, diag0val));
3664 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3665 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3666 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3667 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3668 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3669 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3671 /* Set the DiagRwEn and Disable ARM bits */
3672 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3674 fwSize = (pFwHeader->ImageSize + 3)/4;
3675 ptrFw = (u32 *) pFwHeader;
3677 /* Write the LoadStartAddress to the DiagRw Address Register
3678 * using Programmed IO
3680 if (ioc->errata_flag_1064)
3681 pci_enable_io_access(ioc->pcidev);
3683 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3684 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3685 ioc->name, pFwHeader->LoadStartAddress));
3687 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3688 ioc->name, fwSize*4, ptrFw));
3690 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3693 nextImage = pFwHeader->NextImageHeaderOffset;
3695 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3697 load_addr = pExtImage->LoadStartAddress;
3699 fwSize = (pExtImage->ImageSize + 3) >> 2;
3700 ptrFw = (u32 *)pExtImage;
3702 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3703 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3704 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3707 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3709 nextImage = pExtImage->NextImageHeaderOffset;
3712 /* Write the IopResetVectorRegAddr */
3713 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3714 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3716 /* Write the IopResetVectorValue */
3717 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3718 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3720 /* Clear the internal flash bad bit - autoincrementing register,
3721 * so must do two writes.
3723 if (ioc->bus_type == SPI) {
3725 * 1030 and 1035 H/W errata, workaround to access
3726 * the ClearFlashBadSignatureBit
3728 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3729 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3730 diagRwData |= 0x40000000;
3731 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3732 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3734 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3735 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3736 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3737 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3740 if (sleepFlag == CAN_SLEEP) {
3747 if (ioc->errata_flag_1064)
3748 pci_disable_io_access(ioc->pcidev);
3750 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3751 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3752 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3753 ioc->name, diag0val));
3754 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3755 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3756 ioc->name, diag0val));
3757 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3759 /* Write 0xFF to reset the sequencer */
3760 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3762 if (ioc->bus_type == SAS) {
3763 ioc_state = mpt_GetIocState(ioc, 0);
3764 if ( (GetIocFacts(ioc, sleepFlag,
3765 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3766 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3767 ioc->name, ioc_state));
3772 for (count=0; count<HZ*20; count++) {
3773 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3774 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3775 "downloadboot successful! (count=%d) IocState=%x\n",
3776 ioc->name, count, ioc_state));
3777 if (ioc->bus_type == SAS) {
3780 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3781 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3782 "downloadboot: SendIocInit failed\n",
3786 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3787 "downloadboot: SendIocInit successful\n",
3791 if (sleepFlag == CAN_SLEEP) {
3797 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3798 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3804 * KickStart - Perform hard reset of MPT adapter.
3805 * @ioc: Pointer to MPT_ADAPTER structure
3806 * @force: Force hard reset
3807 * @sleepFlag: Specifies whether the process can sleep
3809 * This routine places MPT adapter in diagnostic mode via the
3810 * WriteSequence register, and then performs a hard reset of adapter
3811 * via the Diagnostic register.
3813 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3814 * or NO_SLEEP (interrupt thread, use mdelay)
3815 * force - 1 if doorbell active, board fault state
3816 * board operational, IOC_RECOVERY or
3817 * IOC_BRINGUP and there is an alt_ioc.
3821 * 1 - hard reset, READY
3822 * 0 - no reset due to History bit, READY
3823 * -1 - no reset due to History bit but not READY
3824 * OR reset but failed to come READY
3825 * -2 - no reset, could not enter DIAG mode
3826 * -3 - reset but bad FW bit
3829 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3831 int hard_reset_done = 0;
3835 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3836 if (ioc->bus_type == SPI) {
3837 /* Always issue a Msg Unit Reset first. This will clear some
3838 * SCSI bus hang conditions.
3840 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3842 if (sleepFlag == CAN_SLEEP) {
3849 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3850 if (hard_reset_done < 0)
3851 return hard_reset_done;
3853 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3856 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3857 for (cnt=0; cnt<cntdn; cnt++) {
3858 ioc_state = mpt_GetIocState(ioc, 1);
3859 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3860 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3862 return hard_reset_done;
3864 if (sleepFlag == CAN_SLEEP) {
3871 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3872 ioc->name, mpt_GetIocState(ioc, 0)));
3876 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3878 * mpt_diag_reset - Perform hard reset of the adapter.
3879 * @ioc: Pointer to MPT_ADAPTER structure
3880 * @ignore: Set if to honor and clear to ignore
3881 * the reset history bit
3882 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3883 * else set to NO_SLEEP (use mdelay instead)
3885 * This routine places the adapter in diagnostic mode via the
3886 * WriteSequence register and then performs a hard reset of adapter
3887 * via the Diagnostic register. Adapter should be in ready state
3888 * upon successful completion.
3890 * Returns: 1 hard reset successful
3891 * 0 no reset performed because reset history bit set
3892 * -2 enabling diagnostic mode failed
3893 * -3 diagnostic reset failed
3896 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3900 int hard_reset_done = 0;
3903 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3906 /* Clear any existing interrupts */
3907 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3909 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3914 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3915 "address=%p\n", ioc->name, __func__,
3916 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3917 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3918 if (sleepFlag == CAN_SLEEP)
3924 * Call each currently registered protocol IOC reset handler
3925 * with pre-reset indication.
3926 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3927 * MptResetHandlers[] registered yet.
3929 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3930 if (MptResetHandlers[cb_idx])
3931 (*(MptResetHandlers[cb_idx]))(ioc,
3935 for (count = 0; count < 60; count ++) {
3936 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3937 doorbell &= MPI_IOC_STATE_MASK;
3939 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3940 "looking for READY STATE: doorbell=%x"
3942 ioc->name, doorbell, count));
3944 if (doorbell == MPI_IOC_STATE_READY) {
3949 if (sleepFlag == CAN_SLEEP)
3957 /* Use "Diagnostic reset" method! (only thing available!) */
3958 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3960 if (ioc->debug_level & MPT_DEBUG) {
3962 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3963 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3964 ioc->name, diag0val, diag1val));
3967 /* Do the reset if we are told to ignore the reset history
3968 * or if the reset history is 0
3970 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3971 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3972 /* Write magic sequence to WriteSequence register
3973 * Loop until in diagnostic mode
3975 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3976 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3977 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3978 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3979 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3980 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3983 if (sleepFlag == CAN_SLEEP) {
3991 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3992 ioc->name, diag0val);
3997 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3999 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4000 ioc->name, diag0val));
4003 if (ioc->debug_level & MPT_DEBUG) {
4005 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4006 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4007 ioc->name, diag0val, diag1val));
4010 * Disable the ARM (Bug fix)
4013 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4017 * Now hit the reset bit in the Diagnostic register
4018 * (THE BIG HAMMER!) (Clears DRWE bit).
4020 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4021 hard_reset_done = 1;
4022 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4026 * Call each currently registered protocol IOC reset handler
4027 * with pre-reset indication.
4028 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4029 * MptResetHandlers[] registered yet.
4031 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4032 if (MptResetHandlers[cb_idx]) {
4033 mpt_signal_reset(cb_idx,
4034 ioc, MPT_IOC_PRE_RESET);
4036 mpt_signal_reset(cb_idx,
4037 ioc->alt_ioc, MPT_IOC_PRE_RESET);
4043 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4044 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4045 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4049 /* If the DownloadBoot operation fails, the
4050 * IOC will be left unusable. This is a fatal error
4051 * case. _diag_reset will return < 0
4053 for (count = 0; count < 30; count ++) {
4054 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4055 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4059 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4060 ioc->name, diag0val, count));
4062 if (sleepFlag == CAN_SLEEP) {
4068 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4069 printk(MYIOC_s_WARN_FMT
4070 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4074 /* Wait for FW to reload and for board
4075 * to go to the READY state.
4076 * Maximum wait is 60 seconds.
4077 * If fail, no error will check again
4078 * with calling program.
4080 for (count = 0; count < 60; count ++) {
4081 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4082 doorbell &= MPI_IOC_STATE_MASK;
4084 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4085 "looking for READY STATE: doorbell=%x"
4086 " count=%d\n", ioc->name, doorbell, count));
4088 if (doorbell == MPI_IOC_STATE_READY) {
4093 if (sleepFlag == CAN_SLEEP) {
4100 if (doorbell != MPI_IOC_STATE_READY)
4101 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4102 "after reset! IocState=%x", ioc->name,
4107 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4108 if (ioc->debug_level & MPT_DEBUG) {
4110 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4111 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4112 ioc->name, diag0val, diag1val));
4115 /* Clear RESET_HISTORY bit! Place board in the
4116 * diagnostic mode to update the diag register.
4118 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4120 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4121 /* Write magic sequence to WriteSequence register
4122 * Loop until in diagnostic mode
4124 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4125 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4126 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4127 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4128 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4129 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4132 if (sleepFlag == CAN_SLEEP) {
4140 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4141 ioc->name, diag0val);
4144 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4146 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4147 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4148 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4149 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4150 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4154 /* Disable Diagnostic Mode
4156 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4158 /* Check FW reload status flags.
4160 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4161 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4162 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4163 ioc->name, diag0val);
4167 if (ioc->debug_level & MPT_DEBUG) {
4169 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4170 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4171 ioc->name, diag0val, diag1val));
4175 * Reset flag that says we've enabled event notification
4177 ioc->facts.EventState = 0;
4180 ioc->alt_ioc->facts.EventState = 0;
4182 return hard_reset_done;
4185 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4187 * SendIocReset - Send IOCReset request to MPT adapter.
4188 * @ioc: Pointer to MPT_ADAPTER structure
4189 * @reset_type: reset type, expected values are
4190 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4191 * @sleepFlag: Specifies whether the process can sleep
4193 * Send IOCReset request to the MPT adapter.
4195 * Returns 0 for success, non-zero for failure.
4198 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4204 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4205 ioc->name, reset_type));
4206 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4207 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4210 /* FW ACK'd request, wait for READY state
4213 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4215 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4219 if (sleepFlag != CAN_SLEEP)
4222 printk(MYIOC_s_ERR_FMT
4223 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4224 ioc->name, state, (int)((count+5)/HZ));
4228 if (sleepFlag == CAN_SLEEP) {
4231 mdelay (1); /* 1 msec delay */
4236 * Cleanup all event stuff for this IOC; re-issue EventNotification
4237 * request if needed.
4239 if (ioc->facts.Function)
4240 ioc->facts.EventState = 0;
4245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4247 * initChainBuffers - Allocate memory for and initialize chain buffers
4248 * @ioc: Pointer to MPT_ADAPTER structure
4250 * Allocates memory for and initializes chain buffers,
4251 * chain buffer control arrays and spinlock.
4254 initChainBuffers(MPT_ADAPTER *ioc)
4257 int sz, ii, num_chain;
4258 int scale, num_sge, numSGE;
4260 /* ReqToChain size must equal the req_depth
4263 if (ioc->ReqToChain == NULL) {
4264 sz = ioc->req_depth * sizeof(int);
4265 mem = kmalloc(sz, GFP_ATOMIC);
4269 ioc->ReqToChain = (int *) mem;
4270 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4271 ioc->name, mem, sz));
4272 mem = kmalloc(sz, GFP_ATOMIC);
4276 ioc->RequestNB = (int *) mem;
4277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4278 ioc->name, mem, sz));
4280 for (ii = 0; ii < ioc->req_depth; ii++) {
4281 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4284 /* ChainToChain size must equal the total number
4285 * of chain buffers to be allocated.
4288 * Calculate the number of chain buffers needed(plus 1) per I/O
4289 * then multiply the maximum number of simultaneous cmds
4291 * num_sge = num sge in request frame + last chain buffer
4292 * scale = num sge per chain buffer if no chain element
4294 scale = ioc->req_sz / ioc->SGE_size;
4295 if (ioc->sg_addr_size == sizeof(u64))
4296 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4298 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4300 if (ioc->sg_addr_size == sizeof(u64)) {
4301 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4302 (ioc->req_sz - 60) / ioc->SGE_size;
4304 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4305 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4307 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4308 ioc->name, num_sge, numSGE));
4310 if (ioc->bus_type == FC) {
4311 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4312 numSGE = MPT_SCSI_FC_SG_DEPTH;
4314 if (numSGE > MPT_SCSI_SG_DEPTH)
4315 numSGE = MPT_SCSI_SG_DEPTH;
4319 while (numSGE - num_sge > 0) {
4321 num_sge += (scale - 1);
4325 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4326 ioc->name, numSGE, num_sge, num_chain));
4328 if (ioc->bus_type == SPI)
4329 num_chain *= MPT_SCSI_CAN_QUEUE;
4330 else if (ioc->bus_type == SAS)
4331 num_chain *= MPT_SAS_CAN_QUEUE;
4333 num_chain *= MPT_FC_CAN_QUEUE;
4335 ioc->num_chain = num_chain;
4337 sz = num_chain * sizeof(int);
4338 if (ioc->ChainToChain == NULL) {
4339 mem = kmalloc(sz, GFP_ATOMIC);
4343 ioc->ChainToChain = (int *) mem;
4344 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4345 ioc->name, mem, sz));
4347 mem = (u8 *) ioc->ChainToChain;
4349 memset(mem, 0xFF, sz);
4353 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4355 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4356 * @ioc: Pointer to MPT_ADAPTER structure
4358 * This routine allocates memory for the MPT reply and request frame
4359 * pools (if necessary), and primes the IOC reply FIFO with
4362 * Returns 0 for success, non-zero for failure.
4365 PrimeIocFifos(MPT_ADAPTER *ioc)
4368 unsigned long flags;
4369 dma_addr_t alloc_dma;
4371 int i, reply_sz, sz, total_size, num_chain;
4376 /* Prime reply FIFO... */
4378 if (ioc->reply_frames == NULL) {
4379 if ( (num_chain = initChainBuffers(ioc)) < 0)
4382 * 1078 errata workaround for the 36GB limitation
4384 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4385 ioc->dma_mask > DMA_BIT_MASK(35)) {
4386 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4387 && !pci_set_consistent_dma_mask(ioc->pcidev,
4388 DMA_BIT_MASK(32))) {
4389 dma_mask = DMA_BIT_MASK(35);
4390 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4391 "setting 35 bit addressing for "
4392 "Request/Reply/Chain and Sense Buffers\n",
4395 /*Reseting DMA mask to 64 bit*/
4396 pci_set_dma_mask(ioc->pcidev,
4398 pci_set_consistent_dma_mask(ioc->pcidev,
4401 printk(MYIOC_s_ERR_FMT
4402 "failed setting 35 bit addressing for "
4403 "Request/Reply/Chain and Sense Buffers\n",
4409 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4410 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4411 ioc->name, ioc->reply_sz, ioc->reply_depth));
4412 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4413 ioc->name, reply_sz, reply_sz));
4415 sz = (ioc->req_sz * ioc->req_depth);
4416 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4417 ioc->name, ioc->req_sz, ioc->req_depth));
4418 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4419 ioc->name, sz, sz));
4422 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4423 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4424 ioc->name, ioc->req_sz, num_chain));
4425 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4426 ioc->name, sz, sz, num_chain));
4429 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4431 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4436 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4437 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4439 memset(mem, 0, total_size);
4440 ioc->alloc_total += total_size;
4442 ioc->alloc_dma = alloc_dma;
4443 ioc->alloc_sz = total_size;
4444 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4445 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4447 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4448 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4450 alloc_dma += reply_sz;
4453 /* Request FIFO - WE manage this! */
4455 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4456 ioc->req_frames_dma = alloc_dma;
4458 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4459 ioc->name, mem, (void *)(ulong)alloc_dma));
4461 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4463 #if defined(CONFIG_MTRR) && 0
4465 * Enable Write Combining MTRR for IOC's memory region.
4466 * (at least as much as we can; "size and base must be
4467 * multiples of 4 kiB"
4469 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4471 MTRR_TYPE_WRCOMB, 1);
4472 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4473 ioc->name, ioc->req_frames_dma, sz));
4476 for (i = 0; i < ioc->req_depth; i++) {
4477 alloc_dma += ioc->req_sz;
4481 ioc->ChainBuffer = mem;
4482 ioc->ChainBufferDMA = alloc_dma;
4484 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4485 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4487 /* Initialize the free chain Q.
4490 INIT_LIST_HEAD(&ioc->FreeChainQ);
4492 /* Post the chain buffers to the FreeChainQ.
4494 mem = (u8 *)ioc->ChainBuffer;
4495 for (i=0; i < num_chain; i++) {
4496 mf = (MPT_FRAME_HDR *) mem;
4497 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4501 /* Initialize Request frames linked list
4503 alloc_dma = ioc->req_frames_dma;
4504 mem = (u8 *) ioc->req_frames;
4506 spin_lock_irqsave(&ioc->FreeQlock, flags);
4507 INIT_LIST_HEAD(&ioc->FreeQ);
4508 for (i = 0; i < ioc->req_depth; i++) {
4509 mf = (MPT_FRAME_HDR *) mem;
4511 /* Queue REQUESTs *internally*! */
4512 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4516 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4518 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4519 ioc->sense_buf_pool =
4520 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4521 if (ioc->sense_buf_pool == NULL) {
4522 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4527 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4528 ioc->alloc_total += sz;
4529 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4530 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4534 /* Post Reply frames to FIFO
4536 alloc_dma = ioc->alloc_dma;
4537 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4538 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4540 for (i = 0; i < ioc->reply_depth; i++) {
4541 /* Write each address to the IOC! */
4542 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4543 alloc_dma += ioc->reply_sz;
4546 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4547 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4549 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4550 "restoring 64 bit addressing\n", ioc->name));
4556 if (ioc->alloc != NULL) {
4558 pci_free_consistent(ioc->pcidev,
4560 ioc->alloc, ioc->alloc_dma);
4561 ioc->reply_frames = NULL;
4562 ioc->req_frames = NULL;
4563 ioc->alloc_total -= sz;
4565 if (ioc->sense_buf_pool != NULL) {
4566 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4567 pci_free_consistent(ioc->pcidev,
4569 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4570 ioc->sense_buf_pool = NULL;
4573 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4574 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4576 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4577 "restoring 64 bit addressing\n", ioc->name));
4582 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4584 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4585 * from IOC via doorbell handshake method.
4586 * @ioc: Pointer to MPT_ADAPTER structure
4587 * @reqBytes: Size of the request in bytes
4588 * @req: Pointer to MPT request frame
4589 * @replyBytes: Expected size of the reply in bytes
4590 * @u16reply: Pointer to area where reply should be written
4591 * @maxwait: Max wait time for a reply (in seconds)
4592 * @sleepFlag: Specifies whether the process can sleep
4594 * NOTES: It is the callers responsibility to byte-swap fields in the
4595 * request which are greater than 1 byte in size. It is also the
4596 * callers responsibility to byte-swap response fields which are
4597 * greater than 1 byte in size.
4599 * Returns 0 for success, non-zero for failure.
4602 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4603 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4605 MPIDefaultReply_t *mptReply;
4610 * Get ready to cache a handshake reply
4612 ioc->hs_reply_idx = 0;
4613 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4614 mptReply->MsgLength = 0;
4617 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4618 * then tell IOC that we want to handshake a request of N words.
4619 * (WRITE u32val to Doorbell reg).
4621 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4622 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4623 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4624 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4627 * Wait for IOC's doorbell handshake int
4629 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4632 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4633 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4635 /* Read doorbell and check for active bit */
4636 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4640 * Clear doorbell int (WRITE 0 to IntStatus reg),
4641 * then wait for IOC to ACKnowledge that it's ready for
4642 * our handshake request.
4644 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4645 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4650 u8 *req_as_bytes = (u8 *) req;
4653 * Stuff request words via doorbell handshake,
4654 * with ACK from IOC for each.
4656 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4657 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4658 (req_as_bytes[(ii*4) + 1] << 8) |
4659 (req_as_bytes[(ii*4) + 2] << 16) |
4660 (req_as_bytes[(ii*4) + 3] << 24));
4662 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4663 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4667 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4668 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4670 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4671 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4674 * Wait for completion of doorbell handshake reply from the IOC
4676 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4679 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4680 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4683 * Copy out the cached reply...
4685 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4686 u16reply[ii] = ioc->hs_reply[ii];
4694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4696 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4697 * @ioc: Pointer to MPT_ADAPTER structure
4698 * @howlong: How long to wait (in seconds)
4699 * @sleepFlag: Specifies whether the process can sleep
4701 * This routine waits (up to ~2 seconds max) for IOC doorbell
4702 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4703 * bit in its IntStatus register being clear.
4705 * Returns a negative value on failure, else wait loop count.
4708 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4714 cntdn = 1000 * howlong;
4716 if (sleepFlag == CAN_SLEEP) {
4719 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4720 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4727 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4728 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4735 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4740 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4741 ioc->name, count, intstat);
4745 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4747 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
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 interrupt
4753 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4755 * Returns a negative value on failure, else wait loop count.
4758 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4764 cntdn = 1000 * howlong;
4765 if (sleepFlag == CAN_SLEEP) {
4767 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4768 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4775 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4776 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4784 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4785 ioc->name, count, howlong));
4789 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4790 ioc->name, count, intstat);
4794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4796 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4797 * @ioc: Pointer to MPT_ADAPTER structure
4798 * @howlong: How long to wait (in seconds)
4799 * @sleepFlag: Specifies whether the process can sleep
4801 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4802 * Reply is cached to IOC private area large enough to hold a maximum
4803 * of 128 bytes of reply data.
4805 * Returns a negative value on failure, else size of reply in WORDS.
4808 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4813 u16 *hs_reply = ioc->hs_reply;
4814 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4817 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4820 * Get first two u16's so we can look at IOC's intended reply MsgLength
4823 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4826 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4827 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4828 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4831 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4832 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4836 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4837 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4838 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4841 * If no error (and IOC said MsgLength is > 0), piece together
4842 * reply 16 bits at a time.
4844 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4845 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4847 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4848 /* don't overflow our IOC hs_reply[] buffer! */
4849 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4850 hs_reply[u16cnt] = hword;
4851 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4854 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4856 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4859 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4864 else if (u16cnt != (2 * mptReply->MsgLength)) {
4867 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4872 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4873 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4875 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4876 ioc->name, t, u16cnt/2));
4880 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4882 * GetLanConfigPages - Fetch LANConfig pages.
4883 * @ioc: Pointer to MPT_ADAPTER structure
4885 * Return: 0 for success
4886 * -ENOMEM if no memory available
4887 * -EPERM if not allowed due to ISR context
4888 * -EAGAIN if no msg frames currently available
4889 * -EFAULT for non-successful reply or no reply (timeout)
4892 GetLanConfigPages(MPT_ADAPTER *ioc)
4894 ConfigPageHeader_t hdr;
4896 LANPage0_t *ppage0_alloc;
4897 dma_addr_t page0_dma;
4898 LANPage1_t *ppage1_alloc;
4899 dma_addr_t page1_dma;
4904 /* Get LAN Page 0 header */
4905 hdr.PageVersion = 0;
4908 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4909 cfg.cfghdr.hdr = &hdr;
4911 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4916 if ((rc = mpt_config(ioc, &cfg)) != 0)
4919 if (hdr.PageLength > 0) {
4920 data_sz = hdr.PageLength * 4;
4921 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4924 memset((u8 *)ppage0_alloc, 0, data_sz);
4925 cfg.physAddr = page0_dma;
4926 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4928 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4930 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4931 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4935 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4938 * Normalize endianness of structure data,
4939 * by byte-swapping all > 1 byte fields!
4948 /* Get LAN Page 1 header */
4949 hdr.PageVersion = 0;
4952 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4953 cfg.cfghdr.hdr = &hdr;
4955 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4959 if ((rc = mpt_config(ioc, &cfg)) != 0)
4962 if (hdr.PageLength == 0)
4965 data_sz = hdr.PageLength * 4;
4967 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4969 memset((u8 *)ppage1_alloc, 0, data_sz);
4970 cfg.physAddr = page1_dma;
4971 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4973 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4975 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4976 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4979 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4982 * Normalize endianness of structure data,
4983 * by byte-swapping all > 1 byte fields!
4991 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4993 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4994 * @ioc: Pointer to MPT_ADAPTER structure
4995 * @persist_opcode: see below
4997 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4998 * devices not currently present.
4999 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5001 * NOTE: Don't use not this function during interrupt time.
5003 * Returns 0 for success, non-zero error
5006 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5008 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5010 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5011 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5012 MPT_FRAME_HDR *mf = NULL;
5013 MPIHeader_t *mpi_hdr;
5015 unsigned long timeleft;
5017 mutex_lock(&ioc->mptbase_cmds.mutex);
5019 /* init the internal cmd struct */
5020 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5021 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5023 /* insure garbage is not sent to fw */
5024 switch(persist_opcode) {
5026 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5027 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5035 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5036 __func__, persist_opcode);
5038 /* Get a MF for this command.
5040 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5041 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5046 mpi_hdr = (MPIHeader_t *) mf;
5047 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5048 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5049 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5050 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5051 sasIoUnitCntrReq->Operation = persist_opcode;
5053 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5054 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5055 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5057 printk(KERN_DEBUG "%s: failed\n", __func__);
5058 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5061 printk(MYIOC_s_WARN_FMT
5062 "Issuing Reset from %s!!, doorbell=0x%08x\n",
5063 ioc->name, __func__, mpt_GetIocState(ioc, 0));
5064 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5065 mpt_free_msg_frame(ioc, mf);
5070 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5075 sasIoUnitCntrReply =
5076 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5077 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5078 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5079 __func__, sasIoUnitCntrReply->IOCStatus,
5080 sasIoUnitCntrReply->IOCLogInfo);
5081 printk(KERN_DEBUG "%s: failed\n", __func__);
5084 printk(KERN_DEBUG "%s: success\n", __func__);
5087 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5088 mutex_unlock(&ioc->mptbase_cmds.mutex);
5092 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5095 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5096 MpiEventDataRaid_t * pRaidEventData)
5105 volume = pRaidEventData->VolumeID;
5106 reason = pRaidEventData->ReasonCode;
5107 disk = pRaidEventData->PhysDiskNum;
5108 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5109 flags = (status >> 0) & 0xff;
5110 state = (status >> 8) & 0xff;
5112 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5116 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5117 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5118 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5119 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5120 ioc->name, disk, volume);
5122 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5127 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5128 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5132 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5134 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5138 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5139 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5143 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5144 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5146 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5148 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5150 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5153 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5155 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5156 ? ", quiesced" : "",
5157 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5158 ? ", resync in progress" : "" );
5161 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5162 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5166 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5167 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5171 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5172 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5176 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5177 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5181 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5182 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5184 state == MPI_PHYSDISK0_STATUS_ONLINE
5186 : state == MPI_PHYSDISK0_STATUS_MISSING
5188 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5190 : state == MPI_PHYSDISK0_STATUS_FAILED
5192 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5194 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5195 ? "offline requested"
5196 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5197 ? "failed requested"
5198 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5201 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5202 ? ", out of sync" : "",
5203 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5204 ? ", quiesced" : "" );
5207 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5208 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5212 case MPI_EVENT_RAID_RC_SMART_DATA:
5213 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5214 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5217 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5218 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5224 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5226 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5227 * @ioc: Pointer to MPT_ADAPTER structure
5229 * Returns: 0 for success
5230 * -ENOMEM if no memory available
5231 * -EPERM if not allowed due to ISR context
5232 * -EAGAIN if no msg frames currently available
5233 * -EFAULT for non-successful reply or no reply (timeout)
5236 GetIoUnitPage2(MPT_ADAPTER *ioc)
5238 ConfigPageHeader_t hdr;
5240 IOUnitPage2_t *ppage_alloc;
5241 dma_addr_t page_dma;
5245 /* Get the page header */
5246 hdr.PageVersion = 0;
5249 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5250 cfg.cfghdr.hdr = &hdr;
5252 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5257 if ((rc = mpt_config(ioc, &cfg)) != 0)
5260 if (hdr.PageLength == 0)
5263 /* Read the config page */
5264 data_sz = hdr.PageLength * 4;
5266 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5268 memset((u8 *)ppage_alloc, 0, data_sz);
5269 cfg.physAddr = page_dma;
5270 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5272 /* If Good, save data */
5273 if ((rc = mpt_config(ioc, &cfg)) == 0)
5274 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5276 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5284 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5285 * @ioc: Pointer to a Adapter Strucutre
5286 * @portnum: IOC port number
5288 * Return: -EFAULT if read of config page header fails
5290 * If read of SCSI Port Page 0 fails,
5291 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5292 * Adapter settings: async, narrow
5294 * If read of SCSI Port Page 2 fails,
5295 * Adapter settings valid
5296 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5301 * CHECK - what type of locking mechanisms should be used????
5304 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5309 ConfigPageHeader_t header;
5315 if (!ioc->spi_data.nvram) {
5318 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5319 mem = kmalloc(sz, GFP_ATOMIC);
5323 ioc->spi_data.nvram = (int *) mem;
5325 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5326 ioc->name, ioc->spi_data.nvram, sz));
5329 /* Invalidate NVRAM information
5331 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5332 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5335 /* Read SPP0 header, allocate memory, then read page.
5337 header.PageVersion = 0;
5338 header.PageLength = 0;
5339 header.PageNumber = 0;
5340 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5341 cfg.cfghdr.hdr = &header;
5343 cfg.pageAddr = portnum;
5344 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5346 cfg.timeout = 0; /* use default */
5347 if (mpt_config(ioc, &cfg) != 0)
5350 if (header.PageLength > 0) {
5351 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5353 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5354 cfg.physAddr = buf_dma;
5355 if (mpt_config(ioc, &cfg) != 0) {
5356 ioc->spi_data.maxBusWidth = MPT_NARROW;
5357 ioc->spi_data.maxSyncOffset = 0;
5358 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5359 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5361 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5362 "Unable to read PortPage0 minSyncFactor=%x\n",
5363 ioc->name, ioc->spi_data.minSyncFactor));
5365 /* Save the Port Page 0 data
5367 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5368 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5369 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5371 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5372 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5373 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5374 "noQas due to Capabilities=%x\n",
5375 ioc->name, pPP0->Capabilities));
5377 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5378 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5380 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5381 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5382 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5383 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5384 "PortPage0 minSyncFactor=%x\n",
5385 ioc->name, ioc->spi_data.minSyncFactor));
5387 ioc->spi_data.maxSyncOffset = 0;
5388 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5391 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5393 /* Update the minSyncFactor based on bus type.
5395 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5396 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5398 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5399 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5400 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5401 "HVD or SE detected, minSyncFactor=%x\n",
5402 ioc->name, ioc->spi_data.minSyncFactor));
5407 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5412 /* SCSI Port Page 2 - Read the header then the page.
5414 header.PageVersion = 0;
5415 header.PageLength = 0;
5416 header.PageNumber = 2;
5417 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5418 cfg.cfghdr.hdr = &header;
5420 cfg.pageAddr = portnum;
5421 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5423 if (mpt_config(ioc, &cfg) != 0)
5426 if (header.PageLength > 0) {
5427 /* Allocate memory and read SCSI Port Page 2
5429 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5431 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5432 cfg.physAddr = buf_dma;
5433 if (mpt_config(ioc, &cfg) != 0) {
5434 /* Nvram data is left with INVALID mark
5437 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5439 /* This is an ATTO adapter, read Page2 accordingly
5441 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5442 ATTODeviceInfo_t *pdevice = NULL;
5445 /* Save the Port Page 2 data
5446 * (reformat into a 32bit quantity)
5448 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5449 pdevice = &pPP2->DeviceSettings[ii];
5450 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5453 /* Translate ATTO device flags to LSI format
5455 if (ATTOFlags & ATTOFLAG_DISC)
5456 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5457 if (ATTOFlags & ATTOFLAG_ID_ENB)
5458 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5459 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5460 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5461 if (ATTOFlags & ATTOFLAG_TAGGED)
5462 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5463 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5464 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5466 data = (data << 16) | (pdevice->Period << 8) | 10;
5467 ioc->spi_data.nvram[ii] = data;
5470 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5471 MpiDeviceInfo_t *pdevice = NULL;
5474 * Save "Set to Avoid SCSI Bus Resets" flag
5476 ioc->spi_data.bus_reset =
5477 (le32_to_cpu(pPP2->PortFlags) &
5478 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5481 /* Save the Port Page 2 data
5482 * (reformat into a 32bit quantity)
5484 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5485 ioc->spi_data.PortFlags = data;
5486 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5487 pdevice = &pPP2->DeviceSettings[ii];
5488 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5489 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5490 ioc->spi_data.nvram[ii] = data;
5494 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5498 /* Update Adapter limits with those from NVRAM
5499 * Comment: Don't need to do this. Target performance
5500 * parameters will never exceed the adapters limits.
5506 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5508 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5509 * @ioc: Pointer to a Adapter Strucutre
5510 * @portnum: IOC port number
5512 * Return: -EFAULT if read of config page header fails
5516 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5519 ConfigPageHeader_t header;
5521 /* Read the SCSI Device Page 1 header
5523 header.PageVersion = 0;
5524 header.PageLength = 0;
5525 header.PageNumber = 1;
5526 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5527 cfg.cfghdr.hdr = &header;
5529 cfg.pageAddr = portnum;
5530 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5533 if (mpt_config(ioc, &cfg) != 0)
5536 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5537 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5539 header.PageVersion = 0;
5540 header.PageLength = 0;
5541 header.PageNumber = 0;
5542 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5543 if (mpt_config(ioc, &cfg) != 0)
5546 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5547 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5549 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5550 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5552 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5553 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5558 * mpt_inactive_raid_list_free - This clears this link list.
5559 * @ioc : pointer to per adapter structure
5562 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5564 struct inactive_raid_component_info *component_info, *pNext;
5566 if (list_empty(&ioc->raid_data.inactive_list))
5569 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5570 list_for_each_entry_safe(component_info, pNext,
5571 &ioc->raid_data.inactive_list, list) {
5572 list_del(&component_info->list);
5573 kfree(component_info);
5575 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5579 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5581 * @ioc : pointer to per adapter structure
5582 * @channel : volume channel
5583 * @id : volume target id
5586 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5589 ConfigPageHeader_t hdr;
5590 dma_addr_t dma_handle;
5591 pRaidVolumePage0_t buffer = NULL;
5593 RaidPhysDiskPage0_t phys_disk;
5594 struct inactive_raid_component_info *component_info;
5595 int handle_inactive_volumes;
5597 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5598 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5599 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5600 cfg.pageAddr = (channel << 8) + id;
5601 cfg.cfghdr.hdr = &hdr;
5602 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5604 if (mpt_config(ioc, &cfg) != 0)
5607 if (!hdr.PageLength)
5610 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5616 cfg.physAddr = dma_handle;
5617 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5619 if (mpt_config(ioc, &cfg) != 0)
5622 if (!buffer->NumPhysDisks)
5625 handle_inactive_volumes =
5626 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5627 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5628 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5629 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5631 if (!handle_inactive_volumes)
5634 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5635 for (i = 0; i < buffer->NumPhysDisks; i++) {
5636 if(mpt_raid_phys_disk_pg0(ioc,
5637 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5640 if ((component_info = kmalloc(sizeof (*component_info),
5641 GFP_KERNEL)) == NULL)
5644 component_info->volumeID = id;
5645 component_info->volumeBus = channel;
5646 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5647 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5648 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5649 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5651 list_add_tail(&component_info->list,
5652 &ioc->raid_data.inactive_list);
5654 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5658 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5663 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5664 * @ioc: Pointer to a Adapter Structure
5665 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5666 * @phys_disk: requested payload data returned
5670 * -EFAULT if read of config page header fails or data pointer not NULL
5671 * -ENOMEM if pci_alloc failed
5674 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5675 RaidPhysDiskPage0_t *phys_disk)
5678 ConfigPageHeader_t hdr;
5679 dma_addr_t dma_handle;
5680 pRaidPhysDiskPage0_t buffer = NULL;
5683 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5684 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5685 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5687 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5688 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5689 cfg.cfghdr.hdr = &hdr;
5691 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5693 if (mpt_config(ioc, &cfg) != 0) {
5698 if (!hdr.PageLength) {
5703 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5711 cfg.physAddr = dma_handle;
5712 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5713 cfg.pageAddr = phys_disk_num;
5715 if (mpt_config(ioc, &cfg) != 0) {
5721 memcpy(phys_disk, buffer, sizeof(*buffer));
5722 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5727 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5734 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5735 * @ioc: Pointer to a Adapter Structure
5736 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5739 * returns number paths
5742 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5745 ConfigPageHeader_t hdr;
5746 dma_addr_t dma_handle;
5747 pRaidPhysDiskPage1_t buffer = NULL;
5750 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5751 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5753 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5754 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5756 cfg.cfghdr.hdr = &hdr;
5758 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5760 if (mpt_config(ioc, &cfg) != 0) {
5765 if (!hdr.PageLength) {
5770 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5778 cfg.physAddr = dma_handle;
5779 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5780 cfg.pageAddr = phys_disk_num;
5782 if (mpt_config(ioc, &cfg) != 0) {
5787 rc = buffer->NumPhysDiskPaths;
5791 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5796 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5799 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5800 * @ioc: Pointer to a Adapter Structure
5801 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5802 * @phys_disk: requested payload data returned
5806 * -EFAULT if read of config page header fails or data pointer not NULL
5807 * -ENOMEM if pci_alloc failed
5810 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5811 RaidPhysDiskPage1_t *phys_disk)
5814 ConfigPageHeader_t hdr;
5815 dma_addr_t dma_handle;
5816 pRaidPhysDiskPage1_t buffer = NULL;
5821 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5822 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5825 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5826 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) {
5859 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5860 phys_disk->PhysDiskNum = phys_disk_num;
5861 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5862 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5863 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5864 phys_disk->Path[i].OwnerIdentifier =
5865 buffer->Path[i].OwnerIdentifier;
5866 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5867 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5868 sas_address = le64_to_cpu(sas_address);
5869 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5870 memcpy(&sas_address,
5871 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5872 sas_address = le64_to_cpu(sas_address);
5873 memcpy(&phys_disk->Path[i].OwnerWWID,
5874 &sas_address, sizeof(__le64));
5880 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5885 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5889 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5890 * @ioc: Pointer to a Adapter Strucutre
5894 * -EFAULT if read of config page header fails or data pointer not NULL
5895 * -ENOMEM if pci_alloc failed
5898 mpt_findImVolumes(MPT_ADAPTER *ioc)
5902 dma_addr_t ioc2_dma;
5904 ConfigPageHeader_t header;
5909 if (!ioc->ir_firmware)
5912 /* Free the old page
5914 kfree(ioc->raid_data.pIocPg2);
5915 ioc->raid_data.pIocPg2 = NULL;
5916 mpt_inactive_raid_list_free(ioc);
5918 /* Read IOCP2 header then the page.
5920 header.PageVersion = 0;
5921 header.PageLength = 0;
5922 header.PageNumber = 2;
5923 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5924 cfg.cfghdr.hdr = &header;
5927 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5930 if (mpt_config(ioc, &cfg) != 0)
5933 if (header.PageLength == 0)
5936 iocpage2sz = header.PageLength * 4;
5937 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5941 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5942 cfg.physAddr = ioc2_dma;
5943 if (mpt_config(ioc, &cfg) != 0)
5946 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5950 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5951 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5953 mpt_read_ioc_pg_3(ioc);
5955 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5956 mpt_inactive_raid_volumes(ioc,
5957 pIoc2->RaidVolume[i].VolumeBus,
5958 pIoc2->RaidVolume[i].VolumeID);
5961 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5967 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5972 ConfigPageHeader_t header;
5973 dma_addr_t ioc3_dma;
5976 /* Free the old page
5978 kfree(ioc->raid_data.pIocPg3);
5979 ioc->raid_data.pIocPg3 = NULL;
5981 /* There is at least one physical disk.
5982 * Read and save IOC Page 3
5984 header.PageVersion = 0;
5985 header.PageLength = 0;
5986 header.PageNumber = 3;
5987 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5988 cfg.cfghdr.hdr = &header;
5991 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5994 if (mpt_config(ioc, &cfg) != 0)
5997 if (header.PageLength == 0)
6000 /* Read Header good, alloc memory
6002 iocpage3sz = header.PageLength * 4;
6003 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6007 /* Read the Page and save the data
6008 * into malloc'd memory.
6010 cfg.physAddr = ioc3_dma;
6011 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6012 if (mpt_config(ioc, &cfg) == 0) {
6013 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6015 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6016 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6020 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6026 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6030 ConfigPageHeader_t header;
6031 dma_addr_t ioc4_dma;
6034 /* Read and save IOC Page 4
6036 header.PageVersion = 0;
6037 header.PageLength = 0;
6038 header.PageNumber = 4;
6039 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6040 cfg.cfghdr.hdr = &header;
6043 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6046 if (mpt_config(ioc, &cfg) != 0)
6049 if (header.PageLength == 0)
6052 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6053 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6054 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6057 ioc->alloc_total += iocpage4sz;
6059 ioc4_dma = ioc->spi_data.IocPg4_dma;
6060 iocpage4sz = ioc->spi_data.IocPg4Sz;
6063 /* Read the Page into dma memory.
6065 cfg.physAddr = ioc4_dma;
6066 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6067 if (mpt_config(ioc, &cfg) == 0) {
6068 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6069 ioc->spi_data.IocPg4_dma = ioc4_dma;
6070 ioc->spi_data.IocPg4Sz = iocpage4sz;
6072 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6073 ioc->spi_data.pIocPg4 = NULL;
6074 ioc->alloc_total -= iocpage4sz;
6079 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6083 ConfigPageHeader_t header;
6084 dma_addr_t ioc1_dma;
6088 /* Check the Coalescing Timeout in IOC Page 1
6090 header.PageVersion = 0;
6091 header.PageLength = 0;
6092 header.PageNumber = 1;
6093 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6094 cfg.cfghdr.hdr = &header;
6097 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6100 if (mpt_config(ioc, &cfg) != 0)
6103 if (header.PageLength == 0)
6106 /* Read Header good, alloc memory
6108 iocpage1sz = header.PageLength * 4;
6109 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6113 /* Read the Page and check coalescing timeout
6115 cfg.physAddr = ioc1_dma;
6116 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6117 if (mpt_config(ioc, &cfg) == 0) {
6119 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6120 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6121 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6123 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6126 if (tmp > MPT_COALESCING_TIMEOUT) {
6127 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6129 /* Write NVRAM and current
6132 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6133 if (mpt_config(ioc, &cfg) == 0) {
6134 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6135 ioc->name, MPT_COALESCING_TIMEOUT));
6137 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6138 if (mpt_config(ioc, &cfg) == 0) {
6139 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6140 "Reset NVRAM Coalescing Timeout to = %d\n",
6141 ioc->name, MPT_COALESCING_TIMEOUT));
6143 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6144 "Reset NVRAM Coalescing Timeout Failed\n",
6149 dprintk(ioc, printk(MYIOC_s_WARN_FMT
6150 "Reset of Current Coalescing Timeout Failed!\n",
6156 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6160 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6166 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6169 ConfigPageHeader_t hdr;
6171 ManufacturingPage0_t *pbuf = NULL;
6173 memset(&cfg, 0 , sizeof(CONFIGPARMS));
6174 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6176 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6177 cfg.cfghdr.hdr = &hdr;
6179 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6182 if (mpt_config(ioc, &cfg) != 0)
6185 if (!cfg.cfghdr.hdr->PageLength)
6188 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6189 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6193 cfg.physAddr = buf_dma;
6195 if (mpt_config(ioc, &cfg) != 0)
6198 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6199 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6200 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6205 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6210 * SendEventNotification - Send EventNotification (on or off) request to adapter
6211 * @ioc: Pointer to MPT_ADAPTER structure
6212 * @EvSwitch: Event switch flags
6213 * @sleepFlag: Specifies whether the process can sleep
6216 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6218 EventNotification_t evn;
6219 MPIDefaultReply_t reply_buf;
6221 memset(&evn, 0, sizeof(EventNotification_t));
6222 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6224 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6225 evn.Switch = EvSwitch;
6226 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6228 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6229 "Sending EventNotification (%d) request %p\n",
6230 ioc->name, EvSwitch, &evn));
6232 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6233 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6237 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6239 * SendEventAck - Send EventAck request to MPT adapter.
6240 * @ioc: Pointer to MPT_ADAPTER structure
6241 * @evnp: Pointer to original EventNotification request
6244 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6248 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6249 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6250 ioc->name, __func__));
6254 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6256 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6257 pAck->ChainOffset = 0;
6258 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6260 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6261 pAck->Event = evnp->Event;
6262 pAck->EventContext = evnp->EventContext;
6264 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6271 * mpt_config - Generic function to issue config message
6272 * @ioc: Pointer to an adapter structure
6273 * @pCfg: Pointer to a configuration structure. Struct contains
6274 * action, page address, direction, physical address
6275 * and pointer to a configuration page header
6276 * Page header is updated.
6278 * Returns 0 for success
6279 * -EPERM if not allowed due to ISR context
6280 * -EAGAIN if no msg frames currently available
6281 * -EFAULT for non-successful reply or no reply (timeout)
6284 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6287 ConfigReply_t *pReply;
6288 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6294 u8 page_type = 0, extend_page;
6295 unsigned long timeleft;
6296 unsigned long flags;
6298 u8 issue_hard_reset = 0;
6301 /* Prevent calling wait_event() (below), if caller happens
6302 * to be in ISR context, because that is fatal!
6304 in_isr = in_interrupt();
6306 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6311 /* don't send a config page during diag reset */
6312 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6313 if (ioc->ioc_reset_in_progress) {
6314 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6315 "%s: busy with host reset\n", ioc->name, __func__));
6316 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6319 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6321 /* don't send if no chance of success */
6323 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6324 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6325 "%s: ioc not operational, %d, %xh\n",
6326 ioc->name, __func__, ioc->active,
6327 mpt_GetIocState(ioc, 0)));
6332 mutex_lock(&ioc->mptbase_cmds.mutex);
6333 /* init the internal cmd struct */
6334 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6335 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6337 /* Get and Populate a free Frame
6339 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6340 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6341 "mpt_config: no msg frames!\n", ioc->name));
6346 pReq = (Config_t *)mf;
6347 pReq->Action = pCfg->action;
6349 pReq->ChainOffset = 0;
6350 pReq->Function = MPI_FUNCTION_CONFIG;
6352 /* Assume page type is not extended and clear "reserved" fields. */
6353 pReq->ExtPageLength = 0;
6354 pReq->ExtPageType = 0;
6357 for (ii=0; ii < 8; ii++)
6358 pReq->Reserved2[ii] = 0;
6360 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6361 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6362 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6363 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6365 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6366 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6367 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6368 pReq->ExtPageType = pExtHdr->ExtPageType;
6369 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6371 /* Page Length must be treated as a reserved field for the
6374 pReq->Header.PageLength = 0;
6377 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6379 /* Add a SGE to the config request.
6382 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6384 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6386 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6387 MPI_CONFIG_PAGETYPE_EXTENDED) {
6388 flagsLength |= pExtHdr->ExtPageLength * 4;
6389 page_type = pReq->ExtPageType;
6392 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6393 page_type = pReq->Header.PageType;
6397 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6398 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6399 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6401 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6402 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6403 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6404 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6406 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6408 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6409 "Failed Sending Config request type 0x%x, page 0x%x,"
6410 " action %d, status %xh, time left %ld\n\n",
6411 ioc->name, page_type, pReq->Header.PageNumber,
6412 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6413 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6416 issue_hard_reset = 1;
6420 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6424 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6425 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6426 if (ret == MPI_IOCSTATUS_SUCCESS) {
6428 pCfg->cfghdr.ehdr->ExtPageLength =
6429 le16_to_cpu(pReply->ExtPageLength);
6430 pCfg->cfghdr.ehdr->ExtPageType =
6431 pReply->ExtPageType;
6433 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6434 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6435 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6436 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6441 printk(MYIOC_s_INFO_FMT "Retry completed "
6442 "ret=0x%x timeleft=%ld\n",
6443 ioc->name, ret, timeleft);
6445 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6446 ret, le32_to_cpu(pReply->IOCLogInfo)));
6450 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6451 mutex_unlock(&ioc->mptbase_cmds.mutex);
6452 if (issue_hard_reset) {
6453 issue_hard_reset = 0;
6454 printk(MYIOC_s_WARN_FMT
6455 "Issuing Reset from %s!!, doorbell=0x%08x\n",
6456 ioc->name, __func__, mpt_GetIocState(ioc, 0));
6457 if (retry_count == 0) {
6458 if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6461 mpt_HardResetHandler(ioc, CAN_SLEEP);
6463 mpt_free_msg_frame(ioc, mf);
6464 /* attempt one retry for a timed out command */
6465 if (retry_count < 2) {
6466 printk(MYIOC_s_INFO_FMT
6467 "Attempting Retry Config request"
6468 " type 0x%x, page 0x%x,"
6469 " action %d\n", ioc->name, page_type,
6470 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6481 * mpt_ioc_reset - Base cleanup for hard reset
6482 * @ioc: Pointer to the adapter structure
6483 * @reset_phase: Indicates pre- or post-reset functionality
6485 * Remark: Frees resources with internally generated commands.
6488 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6490 switch (reset_phase) {
6491 case MPT_IOC_SETUP_RESET:
6492 ioc->taskmgmt_quiesce_io = 1;
6493 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6494 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6496 case MPT_IOC_PRE_RESET:
6497 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6498 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6500 case MPT_IOC_POST_RESET:
6501 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6502 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6503 /* wake up mptbase_cmds */
6504 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6505 ioc->mptbase_cmds.status |=
6506 MPT_MGMT_STATUS_DID_IOCRESET;
6507 complete(&ioc->mptbase_cmds.done);
6509 /* wake up taskmgmt_cmds */
6510 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6511 ioc->taskmgmt_cmds.status |=
6512 MPT_MGMT_STATUS_DID_IOCRESET;
6513 complete(&ioc->taskmgmt_cmds.done);
6520 return 1; /* currently means nothing really */
6524 #ifdef CONFIG_PROC_FS /* { */
6525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6527 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6531 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6533 * Returns 0 for success, non-zero for failure.
6536 procmpt_create(void)
6538 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6539 if (mpt_proc_root_dir == NULL)
6542 proc_create("summary", S_IRUGO, mpt_proc_root_dir, &mpt_summary_proc_fops);
6543 proc_create("version", S_IRUGO, mpt_proc_root_dir, &mpt_version_proc_fops);
6547 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6549 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6551 * Returns 0 for success, non-zero for failure.
6554 procmpt_destroy(void)
6556 remove_proc_entry("version", mpt_proc_root_dir);
6557 remove_proc_entry("summary", mpt_proc_root_dir);
6558 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6561 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6563 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6565 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6567 static int mpt_summary_proc_show(struct seq_file *m, void *v)
6569 MPT_ADAPTER *ioc = m->private;
6572 seq_mpt_print_ioc_summary(ioc, m, 1);
6574 list_for_each_entry(ioc, &ioc_list, list) {
6575 seq_mpt_print_ioc_summary(ioc, m, 1);
6582 static int mpt_summary_proc_open(struct inode *inode, struct file *file)
6584 return single_open(file, mpt_summary_proc_show, PDE(inode)->data);
6587 static const struct file_operations mpt_summary_proc_fops = {
6588 .owner = THIS_MODULE,
6589 .open = mpt_summary_proc_open,
6591 .llseek = seq_lseek,
6592 .release = single_release,
6595 static int mpt_version_proc_show(struct seq_file *m, void *v)
6598 int scsi, fc, sas, lan, ctl, targ, dmp;
6601 seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6602 seq_printf(m, " Fusion MPT base driver\n");
6604 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6605 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6607 if (MptCallbacks[cb_idx]) {
6608 switch (MptDriverClass[cb_idx]) {
6610 if (!scsi++) drvname = "SPI host";
6613 if (!fc++) drvname = "FC host";
6616 if (!sas++) drvname = "SAS host";
6619 if (!lan++) drvname = "LAN";
6622 if (!targ++) drvname = "SCSI target";
6625 if (!ctl++) drvname = "ioctl";
6630 seq_printf(m, " Fusion MPT %s driver\n", drvname);
6637 static int mpt_version_proc_open(struct inode *inode, struct file *file)
6639 return single_open(file, mpt_version_proc_show, NULL);
6642 static const struct file_operations mpt_version_proc_fops = {
6643 .owner = THIS_MODULE,
6644 .open = mpt_version_proc_open,
6646 .llseek = seq_lseek,
6647 .release = single_release,
6650 static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
6652 MPT_ADAPTER *ioc = m->private;
6657 mpt_get_fw_exp_ver(expVer, ioc);
6659 seq_printf(m, "%s:", ioc->name);
6660 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6661 seq_printf(m, " (f/w download boot flag set)");
6662 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6663 // seq_printf(m, " CONFIG_CHECKSUM_FAIL!");
6665 seq_printf(m, "\n ProductID = 0x%04x (%s)\n",
6666 ioc->facts.ProductID,
6668 seq_printf(m, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6669 if (ioc->facts.FWImageSize)
6670 seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
6671 seq_printf(m, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6672 seq_printf(m, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6673 seq_printf(m, " EventState = 0x%02x\n", ioc->facts.EventState);
6675 seq_printf(m, " CurrentHostMfaHighAddr = 0x%08x\n",
6676 ioc->facts.CurrentHostMfaHighAddr);
6677 seq_printf(m, " CurrentSenseBufferHighAddr = 0x%08x\n",
6678 ioc->facts.CurrentSenseBufferHighAddr);
6680 seq_printf(m, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6681 seq_printf(m, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6683 seq_printf(m, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6684 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6686 * Rounding UP to nearest 4-kB boundary here...
6688 sz = (ioc->req_sz * ioc->req_depth) + 128;
6689 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6690 seq_printf(m, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6691 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6692 seq_printf(m, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6693 4*ioc->facts.RequestFrameSize,
6694 ioc->facts.GlobalCredits);
6696 seq_printf(m, " Frames @ 0x%p (Dma @ 0x%p)\n",
6697 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6698 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6699 seq_printf(m, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6700 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6701 seq_printf(m, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6702 ioc->facts.CurReplyFrameSize,
6703 ioc->facts.ReplyQueueDepth);
6705 seq_printf(m, " MaxDevices = %d\n",
6706 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6707 seq_printf(m, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6710 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6711 seq_printf(m, " PortNumber = %d (of %d)\n",
6713 ioc->facts.NumberOfPorts);
6714 if (ioc->bus_type == FC) {
6715 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6716 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6717 seq_printf(m, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6718 a[5], a[4], a[3], a[2], a[1], a[0]);
6720 seq_printf(m, " WWN = %08X%08X:%08X%08X\n",
6721 ioc->fc_port_page0[p].WWNN.High,
6722 ioc->fc_port_page0[p].WWNN.Low,
6723 ioc->fc_port_page0[p].WWPN.High,
6724 ioc->fc_port_page0[p].WWPN.Low);
6731 static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file)
6733 return single_open(file, mpt_iocinfo_proc_show, PDE(inode)->data);
6736 static const struct file_operations mpt_iocinfo_proc_fops = {
6737 .owner = THIS_MODULE,
6738 .open = mpt_iocinfo_proc_open,
6740 .llseek = seq_lseek,
6741 .release = single_release,
6743 #endif /* CONFIG_PROC_FS } */
6745 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6747 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6750 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6751 sprintf(buf, " (Exp %02d%02d)",
6752 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6753 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6756 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6757 strcat(buf, " [MDBG]");
6761 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6763 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6764 * @ioc: Pointer to MPT_ADAPTER structure
6765 * @buffer: Pointer to buffer where IOC summary info should be written
6766 * @size: Pointer to number of bytes we wrote (set by this routine)
6767 * @len: Offset at which to start writing in buffer
6768 * @showlan: Display LAN stuff?
6770 * This routine writes (english readable) ASCII text, which represents
6771 * a summary of IOC information, to a buffer.
6774 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6779 mpt_get_fw_exp_ver(expVer, ioc);
6782 * Shorter summary of attached ioc's...
6784 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6787 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6788 ioc->facts.FWVersion.Word,
6790 ioc->facts.NumberOfPorts,
6793 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6794 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6795 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6796 a[5], a[4], a[3], a[2], a[1], a[0]);
6799 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6802 y += sprintf(buffer+len+y, " (disabled)");
6804 y += sprintf(buffer+len+y, "\n");
6809 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
6813 mpt_get_fw_exp_ver(expVer, ioc);
6816 * Shorter summary of attached ioc's...
6818 seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6821 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6822 ioc->facts.FWVersion.Word,
6824 ioc->facts.NumberOfPorts,
6827 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6828 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6829 seq_printf(m, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6830 a[5], a[4], a[3], a[2], a[1], a[0]);
6833 seq_printf(m, ", IRQ=%d", ioc->pci_irq);
6836 seq_printf(m, " (disabled)");
6842 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6843 * @ioc: Pointer to MPT_ADAPTER structure
6845 * Returns 0 for SUCCESS or -1 if FAILED.
6847 * If -1 is return, then it was not possible to set the flags
6850 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6852 unsigned long flags;
6855 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6856 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6857 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6862 ioc->taskmgmt_in_progress = 1;
6863 ioc->taskmgmt_quiesce_io = 1;
6865 ioc->alt_ioc->taskmgmt_in_progress = 1;
6866 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6869 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6872 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6875 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6876 * @ioc: Pointer to MPT_ADAPTER structure
6880 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6882 unsigned long flags;
6884 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6885 ioc->taskmgmt_in_progress = 0;
6886 ioc->taskmgmt_quiesce_io = 0;
6888 ioc->alt_ioc->taskmgmt_in_progress = 0;
6889 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6891 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6893 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6897 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6899 * @ioc: Pointer to MPT_ADAPTER structure
6903 mpt_halt_firmware(MPT_ADAPTER *ioc)
6907 ioc_raw_state = mpt_GetIocState(ioc, 0);
6909 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6910 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6911 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6912 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6913 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6915 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6916 panic("%s: Firmware is halted due to command timeout\n",
6920 EXPORT_SYMBOL(mpt_halt_firmware);
6923 * mpt_SoftResetHandler - Issues a less expensive reset
6924 * @ioc: Pointer to MPT_ADAPTER structure
6925 * @sleepFlag: Indicates if sleep or schedule must be called.
6927 * Returns 0 for SUCCESS or -1 if FAILED.
6929 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6930 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6931 * All posted buffers are freed, and event notification is turned off.
6932 * IOC doesnt reply to any outstanding request. This will transfer IOC
6936 mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6941 unsigned long flags;
6943 unsigned long time_count;
6945 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
6948 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6950 if (mpt_fwfault_debug)
6951 mpt_halt_firmware(ioc);
6953 if (ioc_state == MPI_IOC_STATE_FAULT ||
6954 ioc_state == MPI_IOC_STATE_RESET) {
6955 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6956 "skipping, either in FAULT or RESET state!\n", ioc->name));
6960 if (ioc->bus_type == FC) {
6961 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6962 "skipping, because the bus type is FC!\n", ioc->name));
6966 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6967 if (ioc->ioc_reset_in_progress) {
6968 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6971 ioc->ioc_reset_in_progress = 1;
6972 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6976 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6977 if (MptResetHandlers[cb_idx])
6978 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6981 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6982 if (ioc->taskmgmt_in_progress) {
6983 ioc->ioc_reset_in_progress = 0;
6984 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6987 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6988 /* Disable reply interrupts (also blocks FreeQ) */
6989 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
6991 time_count = jiffies;
6993 rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
6995 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6996 if (MptResetHandlers[cb_idx])
6997 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
7003 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7004 if (ioc_state != MPI_IOC_STATE_READY)
7007 for (ii = 0; ii < 5; ii++) {
7008 /* Get IOC facts! Allow 5 retries */
7009 rc = GetIocFacts(ioc, sleepFlag,
7010 MPT_HOSTEVENT_IOC_RECOVER);
7013 if (sleepFlag == CAN_SLEEP)
7021 rc = PrimeIocFifos(ioc);
7025 rc = SendIocInit(ioc, sleepFlag);
7029 rc = SendEventNotification(ioc, 1, sleepFlag);
7033 if (ioc->hard_resets < -1)
7037 * At this point, we know soft reset succeeded.
7041 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7044 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7045 ioc->ioc_reset_in_progress = 0;
7046 ioc->taskmgmt_quiesce_io = 0;
7047 ioc->taskmgmt_in_progress = 0;
7048 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7050 if (ioc->active) { /* otherwise, hard reset coming */
7051 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7052 if (MptResetHandlers[cb_idx])
7053 mpt_signal_reset(cb_idx, ioc,
7054 MPT_IOC_POST_RESET);
7058 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7059 "SoftResetHandler: completed (%d seconds): %s\n",
7060 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7061 ((rc == 0) ? "SUCCESS" : "FAILED")));
7067 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7068 * @ioc: Pointer to MPT_ADAPTER structure
7069 * @sleepFlag: Indicates if sleep or schedule must be called.
7071 * Returns 0 for SUCCESS or -1 if FAILED.
7072 * Try for softreset first, only if it fails go for expensive
7076 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7079 ret = mpt_SoftResetHandler(ioc, sleepFlag);
7082 ret = mpt_HardResetHandler(ioc, sleepFlag);
7085 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7087 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7091 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7093 * mpt_HardResetHandler - Generic reset handler
7094 * @ioc: Pointer to MPT_ADAPTER structure
7095 * @sleepFlag: Indicates if sleep or schedule must be called.
7097 * Issues SCSI Task Management call based on input arg values.
7098 * If TaskMgmt fails, returns associated SCSI request.
7100 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7101 * or a non-interrupt thread. In the former, must not call schedule().
7103 * Note: A return of -1 is a FATAL error case, as it means a
7104 * FW reload/initialization failed.
7106 * Returns 0 for SUCCESS or -1 if FAILED.
7109 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7113 unsigned long flags;
7114 unsigned long time_count;
7116 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7118 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7119 printk("MF count 0x%x !\n", ioc->mfcnt);
7121 if (mpt_fwfault_debug)
7122 mpt_halt_firmware(ioc);
7124 /* Reset the adapter. Prevent more than 1 call to
7125 * mpt_do_ioc_recovery at any instant in time.
7127 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7128 if (ioc->ioc_reset_in_progress) {
7129 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7132 ioc->ioc_reset_in_progress = 1;
7134 ioc->alt_ioc->ioc_reset_in_progress = 1;
7135 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7138 /* The SCSI driver needs to adjust timeouts on all current
7139 * commands prior to the diagnostic reset being issued.
7140 * Prevents timeouts occurring during a diagnostic reset...very bad.
7141 * For all other protocol drivers, this is a no-op.
7143 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7144 if (MptResetHandlers[cb_idx]) {
7145 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7147 mpt_signal_reset(cb_idx, ioc->alt_ioc,
7148 MPT_IOC_SETUP_RESET);
7152 time_count = jiffies;
7153 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7155 printk(KERN_WARNING MYNAM
7156 ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7157 rc, ioc->name, mpt_GetIocState(ioc, 0));
7159 if (ioc->hard_resets < -1)
7163 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7164 ioc->ioc_reset_in_progress = 0;
7165 ioc->taskmgmt_quiesce_io = 0;
7166 ioc->taskmgmt_in_progress = 0;
7168 ioc->alt_ioc->ioc_reset_in_progress = 0;
7169 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7170 ioc->alt_ioc->taskmgmt_in_progress = 0;
7172 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7174 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7175 if (MptResetHandlers[cb_idx]) {
7176 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7178 mpt_signal_reset(cb_idx,
7179 ioc->alt_ioc, MPT_IOC_POST_RESET);
7184 printk(MYIOC_s_DEBUG_FMT
7185 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7186 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7187 "SUCCESS" : "FAILED")));
7192 #ifdef CONFIG_FUSION_LOGGING
7194 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7200 char *evStr = ioc->evStr;
7202 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7203 evData0 = le32_to_cpu(pEventReply->Data[0]);
7206 case MPI_EVENT_NONE:
7209 case MPI_EVENT_LOG_DATA:
7212 case MPI_EVENT_STATE_CHANGE:
7213 ds = "State Change";
7215 case MPI_EVENT_UNIT_ATTENTION:
7216 ds = "Unit Attention";
7218 case MPI_EVENT_IOC_BUS_RESET:
7219 ds = "IOC Bus Reset";
7221 case MPI_EVENT_EXT_BUS_RESET:
7222 ds = "External Bus Reset";
7224 case MPI_EVENT_RESCAN:
7225 ds = "Bus Rescan Event";
7227 case MPI_EVENT_LINK_STATUS_CHANGE:
7228 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7229 ds = "Link Status(FAILURE) Change";
7231 ds = "Link Status(ACTIVE) Change";
7233 case MPI_EVENT_LOOP_STATE_CHANGE:
7234 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7235 ds = "Loop State(LIP) Change";
7236 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7237 ds = "Loop State(LPE) Change";
7239 ds = "Loop State(LPB) Change";
7241 case MPI_EVENT_LOGOUT:
7244 case MPI_EVENT_EVENT_CHANGE:
7250 case MPI_EVENT_INTEGRATED_RAID:
7252 u8 ReasonCode = (u8)(evData0 >> 16);
7253 switch (ReasonCode) {
7254 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7255 ds = "Integrated Raid: Volume Created";
7257 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7258 ds = "Integrated Raid: Volume Deleted";
7260 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7261 ds = "Integrated Raid: Volume Settings Changed";
7263 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7264 ds = "Integrated Raid: Volume Status Changed";
7266 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7267 ds = "Integrated Raid: Volume Physdisk Changed";
7269 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7270 ds = "Integrated Raid: Physdisk Created";
7272 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7273 ds = "Integrated Raid: Physdisk Deleted";
7275 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7276 ds = "Integrated Raid: Physdisk Settings Changed";
7278 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7279 ds = "Integrated Raid: Physdisk Status Changed";
7281 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7282 ds = "Integrated Raid: Domain Validation Needed";
7284 case MPI_EVENT_RAID_RC_SMART_DATA :
7285 ds = "Integrated Raid; Smart Data";
7287 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7288 ds = "Integrated Raid: Replace Action Started";
7291 ds = "Integrated Raid";
7296 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7297 ds = "SCSI Device Status Change";
7299 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7301 u8 id = (u8)(evData0);
7302 u8 channel = (u8)(evData0 >> 8);
7303 u8 ReasonCode = (u8)(evData0 >> 16);
7304 switch (ReasonCode) {
7305 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7306 snprintf(evStr, EVENT_DESCR_STR_SZ,
7307 "SAS Device Status Change: Added: "
7308 "id=%d channel=%d", id, channel);
7310 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7311 snprintf(evStr, EVENT_DESCR_STR_SZ,
7312 "SAS Device Status Change: Deleted: "
7313 "id=%d channel=%d", id, channel);
7315 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7316 snprintf(evStr, EVENT_DESCR_STR_SZ,
7317 "SAS Device Status Change: SMART Data: "
7318 "id=%d channel=%d", id, channel);
7320 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7321 snprintf(evStr, EVENT_DESCR_STR_SZ,
7322 "SAS Device Status Change: No Persistancy: "
7323 "id=%d channel=%d", id, channel);
7325 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7326 snprintf(evStr, EVENT_DESCR_STR_SZ,
7327 "SAS Device Status Change: Unsupported Device "
7328 "Discovered : id=%d channel=%d", id, channel);
7330 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7331 snprintf(evStr, EVENT_DESCR_STR_SZ,
7332 "SAS Device Status Change: Internal Device "
7333 "Reset : id=%d channel=%d", id, channel);
7335 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7336 snprintf(evStr, EVENT_DESCR_STR_SZ,
7337 "SAS Device Status Change: Internal Task "
7338 "Abort : id=%d channel=%d", id, channel);
7340 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7341 snprintf(evStr, EVENT_DESCR_STR_SZ,
7342 "SAS Device Status Change: Internal Abort "
7343 "Task Set : id=%d channel=%d", id, channel);
7345 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7346 snprintf(evStr, EVENT_DESCR_STR_SZ,
7347 "SAS Device Status Change: Internal Clear "
7348 "Task Set : id=%d channel=%d", id, channel);
7350 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7351 snprintf(evStr, EVENT_DESCR_STR_SZ,
7352 "SAS Device Status Change: Internal Query "
7353 "Task : id=%d channel=%d", id, channel);
7356 snprintf(evStr, EVENT_DESCR_STR_SZ,
7357 "SAS Device Status Change: Unknown: "
7358 "id=%d channel=%d", id, channel);
7363 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7364 ds = "Bus Timer Expired";
7366 case MPI_EVENT_QUEUE_FULL:
7368 u16 curr_depth = (u16)(evData0 >> 16);
7369 u8 channel = (u8)(evData0 >> 8);
7370 u8 id = (u8)(evData0);
7372 snprintf(evStr, EVENT_DESCR_STR_SZ,
7373 "Queue Full: channel=%d id=%d depth=%d",
7374 channel, id, curr_depth);
7377 case MPI_EVENT_SAS_SES:
7378 ds = "SAS SES Event";
7380 case MPI_EVENT_PERSISTENT_TABLE_FULL:
7381 ds = "Persistent Table Full";
7383 case MPI_EVENT_SAS_PHY_LINK_STATUS:
7385 u8 LinkRates = (u8)(evData0 >> 8);
7386 u8 PhyNumber = (u8)(evData0);
7387 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7388 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7389 switch (LinkRates) {
7390 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7391 snprintf(evStr, EVENT_DESCR_STR_SZ,
7392 "SAS PHY Link Status: Phy=%d:"
7393 " Rate Unknown",PhyNumber);
7395 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7396 snprintf(evStr, EVENT_DESCR_STR_SZ,
7397 "SAS PHY Link Status: Phy=%d:"
7398 " Phy Disabled",PhyNumber);
7400 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7401 snprintf(evStr, EVENT_DESCR_STR_SZ,
7402 "SAS PHY Link Status: Phy=%d:"
7403 " Failed Speed Nego",PhyNumber);
7405 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7406 snprintf(evStr, EVENT_DESCR_STR_SZ,
7407 "SAS PHY Link Status: Phy=%d:"
7408 " Sata OOB Completed",PhyNumber);
7410 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7411 snprintf(evStr, EVENT_DESCR_STR_SZ,
7412 "SAS PHY Link Status: Phy=%d:"
7413 " Rate 1.5 Gbps",PhyNumber);
7415 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7416 snprintf(evStr, EVENT_DESCR_STR_SZ,
7417 "SAS PHY Link Status: Phy=%d:"
7418 " Rate 3.0 Gpbs",PhyNumber);
7421 snprintf(evStr, EVENT_DESCR_STR_SZ,
7422 "SAS PHY Link Status: Phy=%d", PhyNumber);
7427 case MPI_EVENT_SAS_DISCOVERY_ERROR:
7428 ds = "SAS Discovery Error";
7430 case MPI_EVENT_IR_RESYNC_UPDATE:
7432 u8 resync_complete = (u8)(evData0 >> 16);
7433 snprintf(evStr, EVENT_DESCR_STR_SZ,
7434 "IR Resync Update: Complete = %d:",resync_complete);
7439 u8 id = (u8)(evData0);
7440 u8 channel = (u8)(evData0 >> 8);
7441 u8 phys_num = (u8)(evData0 >> 24);
7442 u8 ReasonCode = (u8)(evData0 >> 16);
7444 switch (ReasonCode) {
7445 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7446 snprintf(evStr, EVENT_DESCR_STR_SZ,
7447 "IR2: LD State Changed: "
7448 "id=%d channel=%d phys_num=%d",
7449 id, channel, phys_num);
7451 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7452 snprintf(evStr, EVENT_DESCR_STR_SZ,
7453 "IR2: PD State Changed "
7454 "id=%d channel=%d phys_num=%d",
7455 id, channel, phys_num);
7457 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7458 snprintf(evStr, EVENT_DESCR_STR_SZ,
7459 "IR2: Bad Block Table Full: "
7460 "id=%d channel=%d phys_num=%d",
7461 id, channel, phys_num);
7463 case MPI_EVENT_IR2_RC_PD_INSERTED:
7464 snprintf(evStr, EVENT_DESCR_STR_SZ,
7465 "IR2: PD Inserted: "
7466 "id=%d channel=%d phys_num=%d",
7467 id, channel, phys_num);
7469 case MPI_EVENT_IR2_RC_PD_REMOVED:
7470 snprintf(evStr, EVENT_DESCR_STR_SZ,
7472 "id=%d channel=%d phys_num=%d",
7473 id, channel, phys_num);
7475 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7476 snprintf(evStr, EVENT_DESCR_STR_SZ,
7477 "IR2: Foreign CFG Detected: "
7478 "id=%d channel=%d phys_num=%d",
7479 id, channel, phys_num);
7481 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7482 snprintf(evStr, EVENT_DESCR_STR_SZ,
7483 "IR2: Rebuild Medium Error: "
7484 "id=%d channel=%d phys_num=%d",
7485 id, channel, phys_num);
7487 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7488 snprintf(evStr, EVENT_DESCR_STR_SZ,
7489 "IR2: Dual Port Added: "
7490 "id=%d channel=%d phys_num=%d",
7491 id, channel, phys_num);
7493 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7494 snprintf(evStr, EVENT_DESCR_STR_SZ,
7495 "IR2: Dual Port Removed: "
7496 "id=%d channel=%d phys_num=%d",
7497 id, channel, phys_num);
7505 case MPI_EVENT_SAS_DISCOVERY:
7508 ds = "SAS Discovery: Start";
7510 ds = "SAS Discovery: Stop";
7513 case MPI_EVENT_LOG_ENTRY_ADDED:
7514 ds = "SAS Log Entry Added";
7517 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7519 u8 phy_num = (u8)(evData0);
7520 u8 port_num = (u8)(evData0 >> 8);
7521 u8 port_width = (u8)(evData0 >> 16);
7522 u8 primative = (u8)(evData0 >> 24);
7523 snprintf(evStr, EVENT_DESCR_STR_SZ,
7524 "SAS Broadcase Primative: phy=%d port=%d "
7525 "width=%d primative=0x%02x",
7526 phy_num, port_num, port_width, primative);
7530 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7532 u8 reason = (u8)(evData0);
7535 case MPI_EVENT_SAS_INIT_RC_ADDED:
7536 ds = "SAS Initiator Status Change: Added";
7538 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7539 ds = "SAS Initiator Status Change: Deleted";
7542 ds = "SAS Initiator Status Change";
7548 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7550 u8 max_init = (u8)(evData0);
7551 u8 current_init = (u8)(evData0 >> 8);
7553 snprintf(evStr, EVENT_DESCR_STR_SZ,
7554 "SAS Initiator Device Table Overflow: max initiators=%02d "
7555 "current initators=%02d",
7556 max_init, current_init);
7559 case MPI_EVENT_SAS_SMP_ERROR:
7561 u8 status = (u8)(evData0);
7562 u8 port_num = (u8)(evData0 >> 8);
7563 u8 result = (u8)(evData0 >> 16);
7565 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7566 snprintf(evStr, EVENT_DESCR_STR_SZ,
7567 "SAS SMP Error: port=%d result=0x%02x",
7569 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7570 snprintf(evStr, EVENT_DESCR_STR_SZ,
7571 "SAS SMP Error: port=%d : CRC Error",
7573 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7574 snprintf(evStr, EVENT_DESCR_STR_SZ,
7575 "SAS SMP Error: port=%d : Timeout",
7577 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7578 snprintf(evStr, EVENT_DESCR_STR_SZ,
7579 "SAS SMP Error: port=%d : No Destination",
7581 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7582 snprintf(evStr, EVENT_DESCR_STR_SZ,
7583 "SAS SMP Error: port=%d : Bad Destination",
7586 snprintf(evStr, EVENT_DESCR_STR_SZ,
7587 "SAS SMP Error: port=%d : status=0x%02x",
7592 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7594 u8 reason = (u8)(evData0);
7597 case MPI_EVENT_SAS_EXP_RC_ADDED:
7598 ds = "Expander Status Change: Added";
7600 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7601 ds = "Expander Status Change: Deleted";
7604 ds = "Expander Status Change";
7611 * MPT base "custom" events may be added here...
7618 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7621 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7622 "MPT event:(%02Xh) : %s\n",
7623 ioc->name, event, evStr));
7625 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7626 ": Event data:\n"));
7627 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7628 devtverboseprintk(ioc, printk(" %08x",
7629 le32_to_cpu(pEventReply->Data[ii])));
7630 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7633 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7635 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7636 * @ioc: Pointer to MPT_ADAPTER structure
7637 * @pEventReply: Pointer to EventNotification reply frame
7638 * @evHandlers: Pointer to integer, number of event handlers
7640 * Routes a received EventNotificationReply to all currently registered
7642 * Returns sum of event handlers return values.
7645 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7656 * Do platform normalization of values
7658 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7659 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7661 evData0 = le32_to_cpu(pEventReply->Data[0]);
7664 #ifdef CONFIG_FUSION_LOGGING
7666 mpt_display_event_info(ioc, pEventReply);
7670 * Do general / base driver event processing
7673 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7675 u8 evState = evData0 & 0xFF;
7677 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7679 /* Update EventState field in cached IocFacts */
7680 if (ioc->facts.Function) {
7681 ioc->facts.EventState = evState;
7685 case MPI_EVENT_INTEGRATED_RAID:
7686 mptbase_raid_process_event_data(ioc,
7687 (MpiEventDataRaid_t *)pEventReply->Data);
7694 * Should this event be logged? Events are written sequentially.
7695 * When buffer is full, start again at the top.
7697 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7700 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7702 ioc->events[idx].event = event;
7703 ioc->events[idx].eventContext = ioc->eventContext;
7705 for (ii = 0; ii < 2; ii++) {
7707 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7709 ioc->events[idx].data[ii] = 0;
7712 ioc->eventContext++;
7717 * Call each currently registered protocol event handler.
7719 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7720 if (MptEvHandlers[cb_idx]) {
7721 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7722 "Routing Event to event handler #%d\n",
7723 ioc->name, cb_idx));
7724 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7728 /* FIXME? Examine results here? */
7731 * If needed, send (a single) EventAck.
7733 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7734 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7735 "EventAck required\n",ioc->name));
7736 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7737 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7742 *evHandlers = handlers;
7746 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7748 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7749 * @ioc: Pointer to MPT_ADAPTER structure
7750 * @log_info: U32 LogInfo reply word from the IOC
7752 * Refer to lsi/mpi_log_fc.h.
7755 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7757 char *desc = "unknown";
7759 switch (log_info & 0xFF000000) {
7760 case MPI_IOCLOGINFO_FC_INIT_BASE:
7761 desc = "FCP Initiator";
7763 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7764 desc = "FCP Target";
7766 case MPI_IOCLOGINFO_FC_LAN_BASE:
7769 case MPI_IOCLOGINFO_FC_MSG_BASE:
7770 desc = "MPI Message Layer";
7772 case MPI_IOCLOGINFO_FC_LINK_BASE:
7775 case MPI_IOCLOGINFO_FC_CTX_BASE:
7776 desc = "Context Manager";
7778 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7779 desc = "Invalid Field Offset";
7781 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7782 desc = "State Change Info";
7786 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7787 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7792 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7793 * @ioc: Pointer to MPT_ADAPTER structure
7794 * @log_info: U32 LogInfo word from the IOC
7796 * Refer to lsi/sp_log.h.
7799 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7801 u32 info = log_info & 0x00FF0000;
7802 char *desc = "unknown";
7806 desc = "bug! MID not found";
7810 desc = "Parity Error";
7814 desc = "ASYNC Outbound Overrun";
7818 desc = "SYNC Offset Error";
7826 desc = "Msg In Overflow";
7834 desc = "Outbound DMA Overrun";
7838 desc = "Task Management";
7842 desc = "Device Problem";
7846 desc = "Invalid Phase Change";
7850 desc = "Untagged Table Size";
7855 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7858 /* strings for sas loginfo */
7859 static char *originator_str[] = {
7864 static char *iop_code_str[] = {
7866 "Invalid SAS Address", /* 01h */
7868 "Invalid Page", /* 03h */
7869 "Diag Message Error", /* 04h */
7870 "Task Terminated", /* 05h */
7871 "Enclosure Management", /* 06h */
7872 "Target Mode" /* 07h */
7874 static char *pl_code_str[] = {
7876 "Open Failure", /* 01h */
7877 "Invalid Scatter Gather List", /* 02h */
7878 "Wrong Relative Offset or Frame Length", /* 03h */
7879 "Frame Transfer Error", /* 04h */
7880 "Transmit Frame Connected Low", /* 05h */
7881 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7882 "SATA Read Log Receive Data Error", /* 07h */
7883 "SATA NCQ Fail All Commands After Error", /* 08h */
7884 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7885 "Receive Frame Invalid Message", /* 0Ah */
7886 "Receive Context Message Valid Error", /* 0Bh */
7887 "Receive Frame Current Frame Error", /* 0Ch */
7888 "SATA Link Down", /* 0Dh */
7889 "Discovery SATA Init W IOS", /* 0Eh */
7890 "Config Invalid Page", /* 0Fh */
7891 "Discovery SATA Init Timeout", /* 10h */
7894 "IO Not Yet Executed", /* 13h */
7895 "IO Executed", /* 14h */
7896 "Persistent Reservation Out Not Affiliation "
7898 "Open Transmit DMA Abort", /* 16h */
7899 "IO Device Missing Delay Retry", /* 17h */
7900 "IO Cancelled Due to Recieve Error", /* 18h */
7908 "Enclosure Management" /* 20h */
7910 static char *ir_code_str[] = {
7911 "Raid Action Error", /* 00h */
7921 static char *raid_sub_code_str[] = {
7923 "Volume Creation Failed: Data Passed too "
7925 "Volume Creation Failed: Duplicate Volumes "
7926 "Attempted", /* 02h */
7927 "Volume Creation Failed: Max Number "
7928 "Supported Volumes Exceeded", /* 03h */
7929 "Volume Creation Failed: DMA Error", /* 04h */
7930 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7931 "Volume Creation Failed: Error Reading "
7932 "MFG Page 4", /* 06h */
7933 "Volume Creation Failed: Creating Internal "
7934 "Structures", /* 07h */
7943 "Activation failed: Already Active Volume", /* 10h */
7944 "Activation failed: Unsupported Volume Type", /* 11h */
7945 "Activation failed: Too Many Active Volumes", /* 12h */
7946 "Activation failed: Volume ID in Use", /* 13h */
7947 "Activation failed: Reported Failure", /* 14h */
7948 "Activation failed: Importing a Volume", /* 15h */
7959 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7960 "Phys Disk failed: Data Passed too Large", /* 21h */
7961 "Phys Disk failed: DMA Error", /* 22h */
7962 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7963 "Phys Disk failed: Creating Phys Disk Config "
7976 "Compatibility Error: IR Disabled", /* 30h */
7977 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7978 "Compatibility Error: Device not Direct Access "
7979 "Device ", /* 32h */
7980 "Compatibility Error: Removable Device Found", /* 33h */
7981 "Compatibility Error: Device SCSI Version not "
7982 "2 or Higher", /* 34h */
7983 "Compatibility Error: SATA Device, 48 BIT LBA "
7984 "not Supported", /* 35h */
7985 "Compatibility Error: Device doesn't have "
7986 "512 Byte Block Sizes", /* 36h */
7987 "Compatibility Error: Volume Type Check Failed", /* 37h */
7988 "Compatibility Error: Volume Type is "
7989 "Unsupported by FW", /* 38h */
7990 "Compatibility Error: Disk Drive too Small for "
7991 "use in Volume", /* 39h */
7992 "Compatibility Error: Phys Disk for Create "
7993 "Volume not Found", /* 3Ah */
7994 "Compatibility Error: Too Many or too Few "
7995 "Disks for Volume Type", /* 3Bh */
7996 "Compatibility Error: Disk stripe Sizes "
7997 "Must be 64KB", /* 3Ch */
7998 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8001 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8003 * mpt_sas_log_info - Log information returned from SAS IOC.
8004 * @ioc: Pointer to MPT_ADAPTER structure
8005 * @log_info: U32 LogInfo reply word from the IOC
8007 * Refer to lsi/mpi_log_sas.h.
8010 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
8012 union loginfo_type {
8021 union loginfo_type sas_loginfo;
8022 char *originator_desc = NULL;
8023 char *code_desc = NULL;
8024 char *sub_code_desc = NULL;
8026 sas_loginfo.loginfo = log_info;
8027 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8028 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8031 originator_desc = originator_str[sas_loginfo.dw.originator];
8033 switch (sas_loginfo.dw.originator) {
8036 if (sas_loginfo.dw.code <
8037 ARRAY_SIZE(iop_code_str))
8038 code_desc = iop_code_str[sas_loginfo.dw.code];
8041 if (sas_loginfo.dw.code <
8042 ARRAY_SIZE(pl_code_str))
8043 code_desc = pl_code_str[sas_loginfo.dw.code];
8046 if (sas_loginfo.dw.code >=
8047 ARRAY_SIZE(ir_code_str))
8049 code_desc = ir_code_str[sas_loginfo.dw.code];
8050 if (sas_loginfo.dw.subcode >=
8051 ARRAY_SIZE(raid_sub_code_str))
8053 if (sas_loginfo.dw.code == 0)
8055 raid_sub_code_str[sas_loginfo.dw.subcode];
8061 if (sub_code_desc != NULL)
8062 printk(MYIOC_s_INFO_FMT
8063 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8064 " SubCode={%s} cb_idx %s\n",
8065 ioc->name, log_info, originator_desc, code_desc,
8066 sub_code_desc, MptCallbacksName[cb_idx]);
8067 else if (code_desc != NULL)
8068 printk(MYIOC_s_INFO_FMT
8069 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8070 " SubCode(0x%04x) cb_idx %s\n",
8071 ioc->name, log_info, originator_desc, code_desc,
8072 sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]);
8074 printk(MYIOC_s_INFO_FMT
8075 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8076 " SubCode(0x%04x) cb_idx %s\n",
8077 ioc->name, log_info, originator_desc,
8078 sas_loginfo.dw.code, sas_loginfo.dw.subcode,
8079 MptCallbacksName[cb_idx]);
8082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8084 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8085 * @ioc: Pointer to MPT_ADAPTER structure
8086 * @ioc_status: U32 IOCStatus word from IOC
8087 * @mf: Pointer to MPT request frame
8089 * Refer to lsi/mpi.h.
8092 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8094 Config_t *pReq = (Config_t *)mf;
8095 char extend_desc[EVENT_DESCR_STR_SZ];
8100 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8101 page_type = pReq->ExtPageType;
8103 page_type = pReq->Header.PageType;
8106 * ignore invalid page messages for GET_NEXT_HANDLE
8108 form = le32_to_cpu(pReq->PageAddress);
8109 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8110 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8111 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8112 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8113 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8114 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8117 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8118 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8119 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8123 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8124 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8125 page_type, pReq->Header.PageNumber, pReq->Action, form);
8127 switch (ioc_status) {
8129 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8130 desc = "Config Page Invalid Action";
8133 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8134 desc = "Config Page Invalid Type";
8137 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8138 desc = "Config Page Invalid Page";
8141 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8142 desc = "Config Page Invalid Data";
8145 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8146 desc = "Config Page No Defaults";
8149 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8150 desc = "Config Page Can't Commit";
8157 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8158 ioc->name, ioc_status, desc, extend_desc));
8162 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8163 * @ioc: Pointer to MPT_ADAPTER structure
8164 * @ioc_status: U32 IOCStatus word from IOC
8165 * @mf: Pointer to MPT request frame
8167 * Refer to lsi/mpi.h.
8170 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8172 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8177 /****************************************************************************/
8178 /* Common IOCStatus values for all replies */
8179 /****************************************************************************/
8181 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8182 desc = "Invalid Function";
8185 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8189 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8190 desc = "Invalid SGL";
8193 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8194 desc = "Internal Error";
8197 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8201 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8202 desc = "Insufficient Resources";
8205 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8206 desc = "Invalid Field";
8209 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8210 desc = "Invalid State";
8213 /****************************************************************************/
8214 /* Config IOCStatus values */
8215 /****************************************************************************/
8217 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8218 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8219 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8220 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8221 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8222 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8223 mpt_iocstatus_info_config(ioc, status, mf);
8226 /****************************************************************************/
8227 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8229 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8231 /****************************************************************************/
8233 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8234 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8235 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8236 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8237 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8238 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8239 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8240 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8241 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8242 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8243 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8244 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8245 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8248 /****************************************************************************/
8249 /* SCSI Target values */
8250 /****************************************************************************/
8252 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8253 desc = "Target: Priority IO";
8256 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8257 desc = "Target: Invalid Port";
8260 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8261 desc = "Target Invalid IO Index:";
8264 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8265 desc = "Target: Aborted";
8268 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8269 desc = "Target: No Conn Retryable";
8272 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8273 desc = "Target: No Connection";
8276 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8277 desc = "Target: Transfer Count Mismatch";
8280 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8281 desc = "Target: STS Data not Sent";
8284 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8285 desc = "Target: Data Offset Error";
8288 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8289 desc = "Target: Too Much Write Data";
8292 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8293 desc = "Target: IU Too Short";
8296 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8297 desc = "Target: ACK NAK Timeout";
8300 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8301 desc = "Target: Nak Received";
8304 /****************************************************************************/
8305 /* Fibre Channel Direct Access values */
8306 /****************************************************************************/
8308 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8309 desc = "FC: Aborted";
8312 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8313 desc = "FC: RX ID Invalid";
8316 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8317 desc = "FC: DID Invalid";
8320 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8321 desc = "FC: Node Logged Out";
8324 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8325 desc = "FC: Exchange Canceled";
8328 /****************************************************************************/
8330 /****************************************************************************/
8332 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8333 desc = "LAN: Device not Found";
8336 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8337 desc = "LAN: Device Failure";
8340 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8341 desc = "LAN: Transmit Error";
8344 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8345 desc = "LAN: Transmit Aborted";
8348 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8349 desc = "LAN: Receive Error";
8352 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8353 desc = "LAN: Receive Aborted";
8356 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8357 desc = "LAN: Partial Packet";
8360 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8361 desc = "LAN: Canceled";
8364 /****************************************************************************/
8365 /* Serial Attached SCSI values */
8366 /****************************************************************************/
8368 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8369 desc = "SAS: SMP Request Failed";
8372 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8373 desc = "SAS: SMP Data Overrun";
8384 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8385 ioc->name, status, desc));
8388 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8389 EXPORT_SYMBOL(mpt_attach);
8390 EXPORT_SYMBOL(mpt_detach);
8392 EXPORT_SYMBOL(mpt_resume);
8393 EXPORT_SYMBOL(mpt_suspend);
8395 EXPORT_SYMBOL(ioc_list);
8396 EXPORT_SYMBOL(mpt_register);
8397 EXPORT_SYMBOL(mpt_deregister);
8398 EXPORT_SYMBOL(mpt_event_register);
8399 EXPORT_SYMBOL(mpt_event_deregister);
8400 EXPORT_SYMBOL(mpt_reset_register);
8401 EXPORT_SYMBOL(mpt_reset_deregister);
8402 EXPORT_SYMBOL(mpt_device_driver_register);
8403 EXPORT_SYMBOL(mpt_device_driver_deregister);
8404 EXPORT_SYMBOL(mpt_get_msg_frame);
8405 EXPORT_SYMBOL(mpt_put_msg_frame);
8406 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8407 EXPORT_SYMBOL(mpt_free_msg_frame);
8408 EXPORT_SYMBOL(mpt_send_handshake_request);
8409 EXPORT_SYMBOL(mpt_verify_adapter);
8410 EXPORT_SYMBOL(mpt_GetIocState);
8411 EXPORT_SYMBOL(mpt_print_ioc_summary);
8412 EXPORT_SYMBOL(mpt_HardResetHandler);
8413 EXPORT_SYMBOL(mpt_config);
8414 EXPORT_SYMBOL(mpt_findImVolumes);
8415 EXPORT_SYMBOL(mpt_alloc_fw_memory);
8416 EXPORT_SYMBOL(mpt_free_fw_memory);
8417 EXPORT_SYMBOL(mptbase_sas_persist_operation);
8418 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8420 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8422 * fusion_init - Fusion MPT base driver initialization routine.
8424 * Returns 0 for success, non-zero for failure.
8431 show_mptmod_ver(my_NAME, my_VERSION);
8432 printk(KERN_INFO COPYRIGHT "\n");
8434 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8435 MptCallbacks[cb_idx] = NULL;
8436 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8437 MptEvHandlers[cb_idx] = NULL;
8438 MptResetHandlers[cb_idx] = NULL;
8441 /* Register ourselves (mptbase) in order to facilitate
8442 * EventNotification handling.
8444 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER,
8447 /* Register for hard reset handling callbacks.
8449 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8451 #ifdef CONFIG_PROC_FS
8452 (void) procmpt_create();
8457 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8459 * fusion_exit - Perform driver unload cleanup.
8461 * This routine frees all resources associated with each MPT adapter
8462 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8468 mpt_reset_deregister(mpt_base_index);
8470 #ifdef CONFIG_PROC_FS
8475 module_init(fusion_init);
8476 module_exit(fusion_exit);